我正在将 Laravel 4.2 应用程序迁移到 5.1(从 5.0 开始),并且我的控制台命令单元测试遇到了很多麻烦。我有 artisan 命令,我需要测试生成的控制台输出、正确的问题/响应处理以及与其他服务的交互(使用模拟)。尽管 Laravel 文档有很多优点,但不幸的是,它对测试控制台命令只字不提。
我终于找到了一种创建这些测试的方法,但感觉就像是对这些测试的黑客攻击setLaravel
and setApplication
calls.
有一个更好的方法吗?我希望我可以将我的模拟实例添加到 Laravel IoC 容器中,并让它创建命令来测试正确设置的所有内容。我担心我的单元测试会很容易被较新的 Laravel 版本破坏。
这是我的单元测试:
使用语句:
use Mockery as m;
use App\Console\Commands\AddClientCommand;
use Symfony\Component\Console\Tester\CommandTester;
Setup
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'));
}
作为命令参数提供的输入。检查控制台输出
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;
}
updates
- 这在 Laravel 5.1 中不起作用#11946 https://github.com/laravel/framework/issues/11946