我目前正在与PHPUnit合作,试图在编写测试的同时开发测试,然而,我目前正在编写会话管理器,并且在这样做时遇到了问题……
会话处理类的构造函数是
private function __construct()
{
if (!headers_sent())
{
session_start();
self::$session_id = session_id();
}
}
但是,由于PHPUnit在开始测试之前发送了文本,因此对此对象的任何测试都会返回一个失败的测试,因为HTTP“Header”已经发送……
发布于 2008-10-10 08:17:01
好吧,你的会话管理器基本上是被设计破坏的。为了能够测试某些东西,必须能够将其从副作用中隔离出来。不幸的是,PHP的设计方式鼓励自由使用全局状态(echo
、header
、exit
、session_start
等)。
你能做的最好的事情,就是隔离组件中的副作用,这些副作用可以在运行时交换。这样一来,您的测试就可以使用模拟对象,而活动代码则使用具有真正副作用的适配器。你会发现这在单例模式下不能很好地发挥作用,我猜你正在使用单例模式。因此,您必须使用其他机制来将共享对象分发到您的代码中。您可以从静态注册表开始,但如果您不介意稍微学习一下,还有更好的解决方案。
如果您不能做到这一点,您始终可以选择编写集成测试。例如:使用PHPUnit的等价物WebTestCase
。
发布于 2009-11-09 21:39:02
为phpunit创建一个bootstrap文件,该文件调用:
session_start();
然后像这样启动phpunit:
phpunit --bootstrap pathToBootstrap.php --anotherSwitch /your/test/path/
bootstrap文件在调用之前被调用,所以头文件还没有发送,一切都应该正常工作。
发布于 2010-10-30 23:44:01
在测试运行时,phpUnit会打印输出,因此即使在第一个测试中,headers_sent()也会返回true。
要解决整个测试套件的这个问题,只需在安装脚本中使用ob_start()。
例如,假设有一个名为AllTests.php的文件,它是phpUnit加载的第一个文件。该脚本可能如下所示:
<?php
ob_start();
require_once 'YourFramework/AllTests.php';
class AllTests {
public static function suite() {
$suite = new PHPUnit_Framework_TestSuite('YourFramework');
$suite->addTest(YourFramework_AllTests::suite());
return $suite;
}
}
https://stackoverflow.com/questions/190292
复制相似问题