Я переношу свое приложение Laravel 4.2 на 5.1 (начиная с 5.0) и много проблем с моими тестовыми модулями консоли. У меня есть команды мастеров, для которых мне нужно протестировать выпущенный выпуск консоли, правильную обработку вопросов / ответов и взаимодействие с другими службами (с использованием mocks). По всем его достоинствам, к сожалению, доктрины 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 // (eg 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; }
Я сделал это раньше: моя консольная команда возвращает ответ 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); }
Поэтому, если вы хотите поместить это в свой собственный класс тестера команд или как функцию в TestCase и т. Д. … до вас.