【问题标题】:PHPUnit Test Suite - Cannot redeclare class Mocking & Concrete classesPHPUnit 测试套件 - 无法重新声明类模拟和具体类
【发布时间】:2011-12-06 05:49:57
【问题描述】:

这是我的问题。

我有一个正在测试几个类的测试套件。我的类都使用依赖注入。

我有一个名为 scheduleHandler 的类,它通过了所有测试。然后我的另一个类 ruleHandler 有一个需要 scheduleHandler 实例的方法。我不想传入真正的 scheduleHandler 所以我尝试创建一个模拟 scheduleHandler 来注入。

我遇到的问题是,因为 scheduleHandler 类是在上面的 ruleHandler 套件中测试的,所以当创建模拟时我得到:-

PHP Fatal error:  Cannot redeclare class scheduleHandler

如果我不使用测试套件,单独运行测试,一切都很好。

有人知道解决这个问题的方法吗?

【问题讨论】:

  • $mockScheduler = $this->getMock('scheduleHandler');
  • 如果我更改测试套件中的顺序,它会起作用: $this->addTestSuite('scheduleHandlerTest'); $this->addTestSuite('ruleHandlerTest');很奇怪....
  • 你能放一个 var_dump(class_exists('scheduleHandler', false));请在 $this->getMock 调用之前?只是看看我的假设是否有任何优点
  • 你能确认var_dump(get_class($this->getMock('scheduleHandler')))给你类似scheduleHandlerTest_<random hash>的东西
  • @Mike B:是的,我确实得到了结果:- object(Mock_scheduleHandler_47ab6dd0)#208 (3) { ["invocationMocker:protected"]=> NULL ["_observer:private"]=> 数组(0) { } ["_db:private"]=> NULL }

标签: php phpunit


【解决方案1】:

尝试在 Mock 创建中使用命名空间。如果您不在项目代码中使用它们,那么希望它会覆盖全局命名空间并且不会导致冲突

$this->getMock('\SomeTestingFramework\SomeTestClass\scheduleHandler');

【讨论】:

    【解决方案2】:

    到目前为止我的最佳猜测:

    var_dump(class_exists('scheduleHandler', false)); 
    

    为您返回false。这意味着该类还不存在。现在,如果您在 phpunit 尝试从它扩展时自动加载器没有找到该类,phpunit 将创建它自己的类。

    如果你以后在路上,那么从某个地方需要 REAL 类,这些类会发生冲突。

    要对此进行测试,请确保您在创建模拟对象之前需要您的 REAL scheduleHandler 类。

    【讨论】:

    • 是的,如前所述,它确实适用于测试套件中位于 ruleHandler(具有模拟)之上的真正 scheduleHandler。我没有在这些测试中使用自动加载器。它确实有效,但我不喜欢如果订单更改它会如何中断。干杯
    • 所以我的建议是在创建模拟之前 require_once 真正的类。 --- 我知道几乎没有其他方法可以避免这种行为。
    • 是的,这就是我所能做的。当我有更多时间时,我将重新审视这一点并尝试找出导致重新声明的原因。感谢大家的意见!
    • 重新声明的原因与 edorian 所说的完全一样:您手动包含类的模块 告诉 PHPUnit 声明类本身(通过在类存在之前调用 getMock()) .自动装载机将为您省去很多精力和头痛,不使用它简直是愚蠢的。 :)
    【解决方案3】:

    试试$this->getMock('scheduleHandler', array(), array(), '', false)。这将导致 PHPUnit 跳过调用 scheduleHandler::__construct,这可能是由于两次加载一个类而导致的错误。

    【讨论】:

    • 不,没有区别。 PHP 致命错误:无法在 /var/www/fleetManagement/models/scheduleHandler.class.php 中重新声明类 scheduleHandler
    • 您能否在 getMock 调用之后添加 echo '!!!'; die; 之类的内容,以查看该行是否会导致致命错误,或者是否稍后会发生?
    • 上面没有得到回应,致命错误首先发生。
    • 这很奇怪——第五个参数设置为 false,getMock() 不应该在你的代码中调用任何东西,所以它不应该导致致命错误。也许您正在使用一个非常旧的 PHPUnit 版本,它没有该选项 - 您可以检查 phpunit --version 吗?您也可以尝试调用 $this->getMock('scheduleHandler', array(), array(), '', false, false, false) 来禁用自动加载并调用 __clone - 两者都不应该在这里相关,但值得一试。
    • 谢谢。我试过了,它是一样的。这是版本输出:- Sebastian Bergmann 的 PHPUnit 3.5.15。
    猜你喜欢
    • 2012-04-08
    • 2013-06-14
    • 2015-07-14
    • 1970-01-01
    • 2011-03-22
    • 2023-03-29
    • 2016-02-24
    • 2018-02-16
    • 1970-01-01
    相关资源
    最近更新 更多