如何为交互式控制台应用程序编写单元测试

时间:2012-02-06 09:38:14

标签: php console phpunit stdio

我有一个控制台应用程序(写成Symfony2命令),通过STDIN读取用户的输入,并在readline的帮助下,用户输入传递给eval() < / p>

整个过程只是用于“调试shell”(类似于php -a)但在项目环境和依赖注入容器访问中。

我想为这个命令编写单元测试,但是我正在试着用这种行为编写PHPUnit测试的方式(并且可能)吗?

1 个答案:

答案 0 :(得分:7)

我不熟悉Sf2 Command事件,但是Sf2文档有一个关于在http://symfony.com/doc/2.0/components/console.html#testing-commands

测试它的例子

通常,您可以从控制台应用中解除STDINSTDOUT,因此您可以将其替换为其他流资源,例如fopen(php://memory)。而不是readline,您使用

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

我们的想法是让您的组件无需真正的控制台环境即可测试。使用此方法可以在测试中随时检查Stream的内容。 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。另一种方法是使用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示例