如何功能测试控制台的命令输入验证器

时间:2017-03-29 16:53:33

标签: symfony unit-testing symfony-2.8 symfony-console

我想功能测试Symfony command我正在创作。我通过关联个人Question来利用validator助手类:

    $helper = $this->getHelper('question');
    $question = new Question('Enter a valid IP: ');
    $question->setValidator($domainValidator);
    $question->setMaxAttempts(2);

我正在执行的测试是功能,所以为了模拟交互,我在PHPUnit的测试类中添加了类似下面的内容。这是一个摘录:

public function testBadIpRaisesError()
{
            $question = $this->createMock('Symfony\Component\Console\Helper\QuestionHelper');
            $question
                ->method('ask')
                ->will($this->onConsecutiveCalls(
                    '<IP>',
                    true
                ));
    ...
}

protected function createMock($originalClassName)
{
    return $this->getMockBuilder($originalClassName)
                ->disableOriginalConstructor()
                ->disableOriginalClone()
                ->disableArgumentCloning()
                ->disallowMockingUnknownTypes()
                ->getMock();
}
当然,当我测试超出Question帮助器的东西时,这个模拟非常好,但在这种情况下,我想做的是按顺序测试整个事情确保验证器写得很好。

在这种情况下,最好的选择是什么?对我的验证器进行单元测试是可以的,但我想根据用户的观点将其作为黑盒进行功能测试

1 个答案:

答案 0 :(得分:0)

控制台组件正是为此用例提供了一个 CommandTesterhttps://symfony.com/doc/current/console.html#testing-commands。你可能想要做这样的事情:

<?php

class ExampleCommandTest extends \PHPUnit\Framework\TestCase
{
    public function testBadIpRaisesError()
    {
        // For a command 'bin/console example'.
        $commandName = 'example';

        // Set up your Application with your command.
        $application = new \Symfony\Component\Console\Application();
        // Here's where you would inject any mocked dependencies as needed.
        $createdCommand = new WhateverCommand();
        $application->add($createdCommand);
        $foundCommand = $application->find($commandName);

        // Create a CommandTester with your Command class processed by your Application.
        $tester = new \Symfony\Component\Console\Tester\CommandTester($foundCommand);

        // Respond "y" to the first prompt (question) when the command is invoked.
        $tester->setInputs(['y']);

        // Execute the command. This example would be the equivalent of
        // 'bin/console example 127.0.0.1 --ipv6=true'
        $tester->execute([
            'command' => $commandName,
            // Arguments as needed.
            'ip-address' => '127.0.0.1',
            // Options as needed.
            '--ipv6' => true,
        ]);
        
        self::assert('Example output', $tester->getDisplay());
        self::assert(0, $tester->getStatusCode());
    }
}

您可以在我正在从事的项目中看到一些更复杂的工作示例:https://github.com/php-tuf/composer-stager/blob/v0.1.0/tests/Unit/Console/Command/StageCommandTest.php