Laravel 5 Console(Artisan)命令单元测试 [英] Laravel 5 console (artisan) command unit tests

查看:277
本文介绍了Laravel 5 Console(Artisan)命令单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将Laravel 4.2应用程序迁移到5.1(从5.0开始),并且在控制台命令单元测试中遇到了很多麻烦.我有一些工匠命令,需要测试产生的控制台输出,正确的问题/响应处理以及与其他服务的交互(使用模拟).尽管具有所有优点,但Laravel文档在测试控制台命令方面始终保持沉默.

I am migrating my Laravel 4.2 app to 5.1 (starting with 5.0) and am a lot of trouble with my console command unit tests. I have artisan commands for which I need to test the produced console output, proper question/response handling and interactions with other services (using mocks). For all its merits, the Laravel doc is unfortunately silent with regards to testing console commands.

我终于找到了一种创建这些测试的方法,但感觉就像是通过setLaravelsetApplication调用进行的破解.

I finally found a way to create those tests, but it feels like a hack with those setLaravel and setApplication calls.

是否有更好的方法可以做到这一点?我希望可以将我的模拟实例添加到Laravel IoC容器中,并让其创建用于测试所有正确设置的命令.恐怕新的Laravel版本会轻易破坏我的单元测试.

Is there a better way to do this? I wish I could add my mock instances to the Laravel IoC container and let it create the commands to test with everything properly set. I'm afraid my unit tests will break easily with newer Laravel versions.

这是我的单元测试:

使用语句:

use Mockery as m;
use App\Console\Commands\AddClientCommand;
use Symfony\Component\Console\Tester\CommandTester;

设置

public function setUp() {
    parent::setUp();

    $this->store = m::mock('App\Services\Store');

    $this->command = new AddClientCommand($this->store);

    // Taken from laravel/framework artisan command unit tests
    // (e.g. tests/Database/DatabaseMigrationRollbackCommandTest.php)
    $this->command->setLaravel($this->app->make('Illuminate\Contracts\Foundation\Application'));

    // Required to provide input to command questions (provides command->getHelper())
    // Taken from ??? when I first built my command tests in Laravel 4.2
    $this->command->setApplication($this->app->make('Symfony\Component\Console\Application'));
}

作为命令参数提供的输入.检查控制台输出

Input provided as command arguments. Checks console output

public function testReadCommandOutput() {
    $commandTester = new CommandTester($this->command);

    $result = $commandTester->execute([
        '--client-name' => 'New Client',
    ]);

    $this->assertSame(0, $result);
    $templatePath = $this->testTemplate;

    // Check console output
    $this->assertEquals(1, preg_match('/^Client \'New Client\' was added./m', $commandTester->getDisplay()));
}

模拟键盘按键提供的输入

Input provided by simulated keyboard keys

public function testAnswerQuestions() {
    $commandTester = new CommandTester($this->command);

    // Simulate keyboard input in console for new client
    $inputs = $this->command->getHelper('question');
    $inputs->setInputStream($this->getInputStream("New Client\n"));
    $result = $commandTester->execute([]);

    $this->assertSame(0, $result);
    $templatePath = $this->testTemplate;

    // Check console output
    $this->assertEquals(1, preg_match('/^Client \'New Client\' was added./m', $commandTester->getDisplay()));
}

protected function getInputStream($input) {
    $stream = fopen('php://memory', 'r+', false);
    fputs($stream, $input);
    rewind($stream);
    return $stream;
}

更新

  1. 这在Laravel 5.1中不起作用#11946

推荐答案

我之前已经这样做过-我的控制台命令返回了json响应:

I have done this before as follows - my console command returns a json response:

public function getConsoleResponse()
{
    $kernel = $this->app->make(Illuminate\Contracts\Console\Kernel::class);
    $status = $kernel->handle(
        $input = new Symfony\Component\Console\Input\ArrayInput([
            'command' => 'test:command', // put your command name here
        ]),
        $output = new Symfony\Component\Console\Output\BufferedOutput
    );

    return json_decode($output->fetch(), true);
}

因此,如果您要将其放在自己的命令测试器类中,或者作为TestCase中的函数等,由您自己决定.

So if you want to put this in it's own command tester class, or as a function within TestCase etc... up to you.

这篇关于Laravel 5 Console(Artisan)命令单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆