Php Laravel 5控制台(artisan)命令单元测试

Php Laravel 5控制台(artisan)命令单元测试,php,unit-testing,laravel,laravel-5,laravel-5.1,Php,Unit Testing,Laravel,Laravel 5,Laravel 5.1,我正在将我的Laravel4.2应用程序迁移到5.1(从5.0开始),我的控制台命令单元测试遇到了很多麻烦。我有artisan命令,需要测试生成的控制台输出、正确的问题/响应处理以及与其他服务的交互(使用mock)。尽管有很多优点,Laravel文档在测试控制台命令方面不幸是沉默的 我终于找到了创建这些测试的方法,但对于那些setLaravel和setApplication调用,感觉就像是一个黑客 有更好的方法吗?我希望我可以将我的模拟实例添加到Laravel IoC容器中,并让它创建命令,以便

我正在将我的Laravel4.2应用程序迁移到5.1(从5.0开始),我的控制台命令单元测试遇到了很多麻烦。我有artisan命令,需要测试生成的控制台输出、正确的问题/响应处理以及与其他服务的交互(使用mock)。尽管有很多优点,Laravel文档在测试控制台命令方面不幸是沉默的

我终于找到了创建这些测试的方法,但对于那些
setLaravel
setApplication
调用,感觉就像是一个黑客

有更好的方法吗?我希望我可以将我的模拟实例添加到Laravel IoC容器中,并让它创建命令,以便在所有设置都正确的情况下进行测试。我担心我的单元测试会很容易被更新的Laravel版本破坏

下面是我的单元测试:

使用语句:

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

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

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()));
}
由模拟键盘键提供的输入

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;
}
更新
  • 这在Laravel 5.1中不起作用

  • 我以前做过如下操作-我的控制台命令返回json响应:

    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);
    }
    
    所以如果你想把它放在它自己的command tester类中,或者作为TestCase中的函数等等。。。由您决定。

    使用Lightning\Support\Facades\Artisan;
    使用Symfony\Component\Console\Output\BufferedOutput;
    $output=新的BufferedOutput();
    Artisan::call('passport:client'[
    '--password'=>true,
    '--name'=>“临时客户端”,
    “--无交互”=>正确,
    ](单位:百万元),;
    $stringOutput=$output->fetch();
    
    不幸的是,我不得不对涉及动态输入的测试进行注释。根据对该问题的回应,“我们对PRs开放:)5.1对此类更改关闭。”看起来比我的解决方案要好得多!看起来依赖注入也在起作用。我现在没有和拉威尔一起工作,所以我不能测试它。我花了好几个小时来解决它。但这是我现在保留在要点中的片段之一!我只能得到“null”作为thisNice的返回。这一个对我有用,但我接受的答案是否定的。
    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);
    }