【问题标题】:PHPUnit: Disable autoloader for autoload testing problemsPHPUnit:为自动加载测试问题禁用自动加载器
【发布时间】:2012-02-22 08:56:58
【问题描述】:

我的项目中有一个管理自动加载的类。该类的每个新实例都将其自动加载功能添加到 SPL 自动加载堆栈中,取消设置一个实例会从堆栈中删除它自己的实例。该类还导出了一个 register() 和 unregister() 方法,可以让您暂时将其从自动加载堆栈中删除。

我正在尝试为自动加载器编写单元测试,但遇到了一些问题。我在我的 PHPUnit 引导脚本中包含了自动加载器,因此其他被测类可以像在正常使用下一样自动加载。我想在自动加载器单元测试期间禁用此行为,因为虽然我可以在不禁用正常自动加载器的情况下进行单元测试,但由于自动加载器的实例,我无法确定我的单元测试是通过还是失败引导程序或我正在测试的实例。

我尝试在我的引导文件中执行以下操作:

$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
}

我认为这会起作用,但不幸的是,当我运行所有单元测试时它只是抛出一个错误,显然是因为 autloader 不适用于任何其他单元测试。

我怀疑 PHPUnit 在运行所有测试之前会初始化所有单元测试类,而我的自动加载器测试类正在阻止其他测试类自动加载它们要测试的类。这个对吗?

有什么方法可以解决这个问题吗?除了在测试构造函数中执行此操作之外,我还能以某种方式禁用默认自动加载器吗?在这种情况下的任何建议将不胜感激。

【问题讨论】:

    标签: php unit-testing phpunit autoload


    【解决方案1】:

    自动加载器不适用于其他测试的原因是 PHPUnit 在运行任何测试之前实例化所有测试用例实例(每个测试方法和数据提供者方法一个)并永久保留它们。您的析构函数只有在所有测试都运行后才会运行。如您所见,您必须将它们移至setUp()tearDown()。当我最初阅读您的答案时,我认为这就是他们的样子。 :)

    此外,PHPUnit 测试用例构造函数接受必须由重写的构造函数传入的参数——至少是 $name 参数。

    【讨论】:

      【解决方案2】:

      最终我选择将禁用普通自动加载器的代码移至 setup(),并将重新启用它的代码移至 teartown()。完整的测试套件现在似乎工作正常。

      【讨论】:

        【解决方案3】:

        对于我的自动加载单元测试,我为这些测试创建了一些类,这些类位于测试源代码树中。由于测试目录没有注册真正的自动加载,所以它找不到它们。

        如果您想让您的测试防弹,请验证无法使用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');
        }
        

        第一行将触发常规自动加载器,它应该无法加载您的测试类。第二行使用正在测试的自动加载器。第三行验证它确实被加载了。

        【讨论】:

        • @GordonM - 您可以使用class_exists() 来避免禁用正常的自动加载器。
        • 我想禁用普通的自动加载器,以便可以单独测试测试自动加载器。
        猜你喜欢
        • 1970-01-01
        • 2014-10-02
        • 2014-04-16
        • 2015-09-05
        • 1970-01-01
        • 1970-01-01
        • 2012-02-13
        • 2020-04-13
        • 2019-07-09
        相关资源
        最近更新 更多