【发布时间】:2020-06-24 23:11:08
【问题描述】:
我正在将我的 Laravel 4.2 应用程序迁移到 5.1(从 5.0 开始),并且我的控制台命令单元测试遇到了很多麻烦。我有工匠命令,我需要测试生成的控制台输出、正确的问题/响应处理以及与其他服务的交互(使用模拟)。遗憾的是,Laravel 文档在测试控制台命令方面保持沉默。
我终于找到了一种创建这些测试的方法,但感觉就像是对那些 setLaravel 和 setApplication 调用进行了破解。
有没有更好的方法来做到这一点?我希望我可以将我的模拟实例添加到 Laravel IoC 容器中,并让它创建命令来测试所有正确设置的内容。恐怕我的单元测试很容易被较新的 Laravel 版本破坏。
这是我的单元测试:
使用语句:
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'));
}
作为命令参数提供的输入。检查控制台输出
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 中不起作用#11946
【问题讨论】:
-
不幸的是,我不得不注释掉涉及动态输入的测试。 Laravel 的人似乎没有根据对问题的响应将正确测试命令视为优先事项:“我们对 PR 持开放态度。:) 5.1 已因此类更改而关闭。”
标签: php unit-testing laravel laravel-5 laravel-5.1