【问题标题】:How to write unit-tests for interactive console app如何为交互式控制台应用程序编写单元测试
【发布时间】:2012-02-27 19:29:58
【问题描述】:

我有一个控制台应用程序(编写为 Symfony2 命令),它通过STDIN 读取用户的输入,并在readline 的帮助下,然后将用户输入传递给eval()

整个事情只是为了拥有“调试外壳”(类似于php -a)但在项目环境和依赖注入容器访问中。

我想为此命令编写单元测试,但我正在碰壁,关于如何(以及是否可能)为这种行为编写 PHPUnit 测试?

【问题讨论】:

    标签: php console phpunit stdio


    【解决方案1】:

    我不熟悉 Sf2 命令,但 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 示例是

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-23
      • 2020-07-01
      • 1970-01-01
      • 2016-02-19
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多