如何编写交互式控制台应用程序的单元测试 [英] How to write unit-tests for interactive console app

查看:285
本文介绍了如何编写交互式控制台应用程序的单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个控制台应用程序(写为Symfony2命令),通过 STDIN 并通过 readline ,然后将用户输入传递给 eval()

I have a console app, (written as a Symfony2 command) that is reading input from user via STDIN and with help of readline, user input is then passed to eval()

debug shell(类似于 php -a ),但是在项目env和Dependency Injection容器访问中。

The whole thing is just for having "debug shell" (something like a php -a) but within project env and Dependency Injection container access.

我想为这个命令写单元测试,但我打墙,如何(和可能)写这个行为的PHPUnit测试。

I would like to write unit-tests for this command but I'm hitting wall, on how (and is it possible) write PHPUnit tests for this behavior?

推荐答案

我不熟悉Sf2 Command的东西,但Sf2文档有一个例子,测试它在 http://symfony.com/doc/2.0/components/console.html#testing-commands

I'm not familiar with the Sf2 Command thing, but the Sf2 docs have an example about testing it at http://symfony.com/doc/2.0/components/console.html#testing-commands

一般来说,您可以从控制台应用程序中解除 STDIN STDOUT ,以便将其替换为另一个流资源,例如 fopen(php:// memory)。而不是 readline ,您使用

In general, you could decouple STDIN and STDOUT from your console app so you can replace it with another stream resource, like fopen(php://memory). Instead of readline, you use

fwrite($outputStream, 'Prompt');
$line = stream_get_line($inputStream, 1024, PHP_EOL);

这个想法是让你的组件可以测试而不需要真正的控制台环境。使用此方法允许您在测试中随时检查Stream的内容。 因此,如果您在控制台应用中运行命令foo,并想要测试输出是bar,您只需回滚适当的资源和阅读它的内容。另一种方法是使用 SplTempFileObject

The idea is to make your component testable without requiring the real console environment. Using this approach allows you to check the contents of the Stream at any time in your test. So if you run Command "foo" in your console app and want to test that the output is "bar" you simply rewind the appropriate resource and read it's content. An alternative would be to use SplTempFileObject.

class ConsoleApp
…
    public function __construct($inputStream, $outputStream)
    {
        $this->inputStream = $inputStream;
        $this->outputStream = $outputStream;
    }
}

在现实世界中,应用

$app = new ConsoleApp(STDIN, STDOUT);

但在测试中,您可以设置 ConsoleApp 与您选择的流:

But in your test you can setup the ConsoleApp with a stream of your choice:

public function setup()
{
    $i = fopen('php://memory', 'w');
    $o = fopen('php://memory', 'w');
    $this->consoleApp = new ConsoleApp($i, $o);
}

对于outstream使用此方法的UnitTest示例为

An example of a UnitTest using this method for the outstream would be

  • https://github.com/gooh/InterfaceDistiller/blob/master/tests/unit/Controller/CommandLineTest.php

这篇关于如何编写交互式控制台应用程序的单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆