我正在进行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可以解决问题,但遗憾的是,我无法将此扩展程序安装到我们的预览和生产环境中,每个应用程序都会自动运行测试部署。
答案 0 :(得分:3)
好吧,我想出了问题:因为应用程序是一个MVC架构,在调度期间调用的exit;
是一个糟糕的方法。
而不是它,在正确设置响应头之后(为了重定向),我一直返回false,直到它返回到调度进程。在这种情况下,我不再需要调用exit;
。
此案例的单元测试运行平稳,无需任何更改(它是在测试类中exit;
调用之前实现的。)