我的项目中有一个管理自动加载的课程。该类的每个新实例都将其自动加载功能添加到SPL自动加载堆栈,并且取消设置实例会从堆栈中删除其自己的实例。该类还导出一个register()和unregister()方法,该方法允许您临时从自动加载堆栈中删除它。
我正在尝试为自动加载器编写单元测试,但遇到了一些问题。我在我的PHPUnit引导程序脚本中包含自动加载器,因此其他正在测试的类可以像正常使用时那样自动加载。我想在自动加载器单元测试期间禁用此行为,因为我可以在不禁用普通自动加载器的情况下进行单元测试,但由于自动加载器的实例,我无法确定我的单元测试是否正在通过或失败我正在测试的bootstrap或实例。
我尝试在我的bootstrap文件中执行以下操作:
$unitTestAutoloader = new gordian\reefknot\autoload\Autoload ();
然后在我的单元测试中实现以下代码:
namespace gordian\reefknot\autoload;
use gordian\exampleclasses;
/**
* Test class for Autoload.
* Generated by PHPUnit on 2011-12-17 at 18:10:33.
*/
class AutoloadTest extends \PHPUnit_Framework_TestCase
{
/**
* @var gordian\reefknot\autoload\Autoload
*/
protected $object;
public function __construct ()
{
// Disable the unit test autoloader for the duration of the following test
global $unitTestAutoloader;
$unitTestAutoloader -> unregister ();
}
public function __destruct ()
{
// Restore normal autoloading when the test is done
global $unitTestAutoloader;
$unitTestAutoloader -> register ();
}
/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp ()
{
$this -> object = new Autoload ('\\', 'gordian\exampleclasses', __DIR__ . '/exampleclasses');
}
// Unit tests go here
}
我认为这样可行,但不幸的是,当我运行所有单元测试时,它只是抛出一个错误,显然是因为自动加载器不能用于任何其他单元测试。
我怀疑PHPUnit在运行所有测试之前初始化所有单元测试类,而我的自动加载器测试类阻止其他测试类自动加载他们要测试的类。它是否正确?
有什么方法可以解决这个问题吗?除了在测试构造函数中执行此操作之外,我能否以某种方式禁用默认自动加载器?在这种情况下的任何建议将不胜感激。
答案 0 :(得分:1)
自动加载器不适用于其他测试的原因是PHPUnit在运行任何测试之前实例化所有测试用例实例(每个测试方法和数据提供者方法一个)并永久保留它们。只有在所有测试运行后,析构函数才会运行。如您所见,您必须将这些内容移至setUp()
和tearDown()
。我认为这是我最初阅读你的答案时的样子。 :)
此外,PHPUnit测试用例构造函数接受必须由重写的构造函数传递的参数 - 至少是$name
参数。
答案 1 :(得分:0)
对于我的自动加载单元测试,我为测试源树中的这些测试创建了一些类。由于测试目录未在真实自动加载中注册,因此无法找到它们。
如果您想让测试防弹,请使用class_exists()
验证无法正常加载该类。
function testAutoloadLoadsClass() {
self::assertFalse(class_exists('My_Test_Class'), 'Class should not load normally');
self::assertTrue($this->fixture->autoload('My_Test_Class'), 'Class should load');
self::assertTrue(class_exists('My_Test_Class'), 'Class should be loaded now');
}
第一行将触发常规自动加载器,它应该无法加载您的测试类。第二行使用被测试的自动加载器。第三行验证它实际上已加载。
答案 2 :(得分:0)
最终我选择移动代码以禁用普通自动加载器setup()和代码以重新启用它为teartown()。完整的测试套件现在似乎工作正常。