У меня есть консольное приложение (написанное как команда Symfony2), которое считывает ввод от пользователя через STDIN
и с помощью readline
, пользовательский ввод затем передается в eval()
Все дело только в том, что у вас есть «отладочная оболочка» (что-то вроде php -a
), но в рамках проекта env и доступа к контейнерам зависимостей.
Я хотел бы написать unit-tests для этой команды, но я нажимаю на стену, как (и это возможно) писать тесты PHPUnit для этого поведения?
Я не знаком с вещью Sf2 Command, но в документах Sf2 есть пример тестирования на http://symfony.com/doc/2.0/components/console.html#testing-commands
В общем, вы можете отделить STDIN
и STDOUT
от своего консольного приложения, чтобы вы могли заменить его другим ресурсом потока, например fopen(php://memory)
. Вместо readline
вы используете
fwrite($outputStream, 'Prompt'); $line = stream_get_line($inputStream, 1024, PHP_EOL);
Идея состоит в том, чтобы сделать ваш компонент тестируемым, не требуя реальной среды консоли. Используя этот подход, вы можете в любое время проверить содержимое Stream в своем тесте. Поэтому, если вы запускаете команду «foo» в своем консольном приложении и хотите проверить, что выход «bar», вы просто перематываете соответствующий ресурс и читаете его содержимое . Альтернативой может быть использование SplTempFileObject
.
class ConsoleApp … public function __construct($inputStream, $outputStream) { $this->inputStream = $inputStream; $this->outputStream = $outputStream; } }
В вашем сценарии реального мира вы создадите консольное приложение с
$app = new ConsoleApp(STDIN, STDOUT);
Но в вашем тесте вы можете настроить ConsoleApp
с потоком по вашему выбору:
public function setup() { $i = fopen('php://memory', 'w'); $o = fopen('php://memory', 'w'); $this->consoleApp = new ConsoleApp($i, $o); }
Примером UnitTest, использующим этот метод для выхода, будет