使用需要发送标头的项目进行单元测试

2022-08-30 11:01:42

我目前正在与PHPUnit合作,尝试在编写内容的同时开发测试,但是,我目前正在编写会话管理器,并且这样做时遇到问题...

会话处理类的构造函数是

private function __construct()
{
    if (!headers_sent())
    {
        session_start();
        self::$session_id = session_id();
    }
}

但是,由于 PHPUnit 在开始测试之前发出文本,因此在此对象上的任何测试都会返回失败的测试,因为 HTTP“标头”已发送...


答案 1

好吧,您的会话管理器基本上是故意破坏的。为了能够测试某些东西,必须能够将其与副作用隔离开来。不幸的是,PHP的设计方式是,它鼓励自由使用全局状态(,,,等)。echoheaderexitsession_start

您可以做的最好的事情是隔离组件中的副作用,该组件可以在运行时交换。这样,您的测试可以使用模拟对象,而实时代码使用具有实际副作用的适配器。你会发现这在单例中效果不佳,我假设你正在使用单例。因此,您必须使用其他一些机制来将共享对象分发到代码中。您可以从静态注册表开始,但如果您不介意学习一下,还有更好的解决方案。

如果你不能做到这一点,你总是可以选择编写集成测试。例如。使用PHPUnit的WebTestCase等效物。


答案 2

为 phpunit 创建一个引导文件,它调用:

session_start();

然后像这样启动 phpunit:

phpunit --bootstrap pathToBootstrap.php --anotherSwitch /your/test/path/

引导程序文件在其他所有内容之前被调用,因此标头尚未发送,一切应该可以正常工作。


推荐