PHPUnit - 如何模拟/存根重定向方法?

时间:2014-01-22 10:36:41

标签: php zend-framework2 phpunit

我正在进行PHP单元测试,我需要测试(虽然需要100%代码覆盖率)一个实现它自己的redirect($url, $code)方法的类。此方法最后调用exit;以确保重定向后没有执行其他代码(并且没有此exit;最终没有完成重定向...)。

现在,这个重定向方法在7种不同的条件下调用,它们都有自己的单元测试用例。如果我在测试类中存在exit;时运行单元测试,则也会退出单元测试。每个测试用例都在测试类似的东西:

$this->assertRedirect();
$this->assertResponseStatusCode(401);

因此,我需要存根 redirect方法,以便设置Location标头以及状态代码。

以下是我要做的事情(使用重定向方法的内容除了exit;部分 - 但它显然不起作用):

    $this->class = $this->getMockBuilder('Some\Name\Space\Class')
            ->disableOriginalConstructor()
            ->getMock();
    $this->class->expects($this->any())
            ->method('redirect')
            ->will($this->returnCallback(function () {
                $this->response->getHeaders()->addHeaderLine('Location: /');
                $this->response->setStatusCode(401);
                $this->response->sendHeaders();
            }));

以前我曾尝试过(并且没有效果):

    $this->class = $this->getMockBuilder('Some\Name\Space\Class')
            ->disableOriginalConstructor()
            ->getMock();
    $this->class->expects($this->any())
            ->method('redirect')
            ->will($this->returnCallback(function () {
                header('Location: /');
            }));

现在,类的目的是在90%的代码覆盖率中重定向某个地方(仅在一种情况下 - 在90行中有2行 - 它不重定向),因此无法存根此重定向(并且无法测试完全重定向)测试用例几乎没有任何意义(这是不愿意的)。

非常感谢任何帮助。

编辑:看起来phpunit/test_helpers可以解决问题,但遗憾的是,我无法将此扩展程序安装到我们的预览和生产环境中,每个应用程序都会自动运行测试部署。

1 个答案:

答案 0 :(得分:3)

好吧,我想出了问题:因为应用程序是一个MVC架构,在调度期间调用的exit;是一个糟糕的方法。

而不是它,在正确设置响应头之后(为了重定向),我一直返回false,直到它返回到调度进程。在这种情况下,我不再需要调用exit;

此案例的单元测试运行平稳,无需任何更改(它是在测试类中exit;调用之前实现的。)