PHPUnit stream_wrapper_register():协议var://已经定义

时间:2013-11-23 18:29:49

标签: php phpunit stream-wrapper

我有一个以前工作得很好的测试套件。它基于FWOpenCartTest,它是PHPUnit_Framework_TestCase的一个重要后代,它实现了一个MVC框架(基于OpenCart)。

今天我不得不向这样的后代添加一个调用,实例化另一个在内部分配var流的类,如下所示:

    // register a variable stream wrapper
    require_once( DIR_SYSTEM . 'library/variable_stream.php' );
    $ok = stream_wrapper_register("var", "VariableStream");
    if (!$ok) {
        trigger_error("Failed to register protocol for a variable stream");
        exit;
    }

从那以后,我无法运行任何测试,因为我一直在获取PHPUnit转储,如:

phpunit ControllerAccountWishListTest.php
PHP Warning:  stream_wrapper_register(): Protocol var:// is already defined. in /var/www/domain.tld/public_html/system/engine/factory.php on line 73
PHP Stack trace:
PHP   1. {main}() /usr/bin/phpunit:0
PHP   2. PHPUnit_TextUI_Command::main() /usr/bin/phpunit:46
PHP   3. PHPUnit_TextUI_Command->run() /usr/share/php/PHPUnit/TextUI/Command.php:129
PHP   4. PHPUnit_Runner_BaseTestRunner->getTest() /usr/share/php/PHPUnit/TextUI/Command.php:150
PHP   5. PHPUnit_Framework_TestSuite->__construct() /usr/share/php/PHPUnit/Runner/BaseTestRunner.php:142
PHP   6. PHPUnit_Framework_TestSuite->addTestMethod() /usr/share/php/PHPUnit/Framework/TestSuite.php:212
PHP   7. PHPUnit_Framework_TestSuite::createTest() /usr/share/php/PHPUnit/Framework/TestSuite.php:834
PHP   8. FWOpenCartTest->__construct() /usr/share/php/PHPUnit/Framework/TestSuite.php:473
PHP   9. Factory->__construct() /var/www/domain.tld/public_html/unittests/VisualPHPUnit/app/test/opencart/FW_OpenCartTest.php:41
PHP  10. stream_wrapper_register() /var/www/domain.tld/public_html/system/engine/factory.php:73
PHP Notice:  Failed to register protocol for a variable stream in /var/www/domain.tld/public_html/system/engine/factory.php on line 75
PHP Stack trace:
PHP   1. {main}() /usr/bin/phpunit:0
PHP   2. PHPUnit_TextUI_Command::main() /usr/bin/phpunit:46
PHP   3. PHPUnit_TextUI_Command->run() /usr/share/php/PHPUnit/TextUI/Command.php:129
PHP   4. PHPUnit_Runner_BaseTestRunner->getTest() /usr/share/php/PHPUnit/TextUI/Command.php:150
PHP   5. PHPUnit_Framework_TestSuite->__construct() /usr/share/php/PHPUnit/Runner/BaseTestRunner.php:142
PHP   6. PHPUnit_Framework_TestSuite->addTestMethod() /usr/share/php/PHPUnit/Framework/TestSuite.php:212
PHP   7. PHPUnit_Framework_TestSuite::createTest() /usr/share/php/PHPUnit/Framework/TestSuite.php:834
PHP   8. FWOpenCartTest->__construct() /usr/share/php/PHPUnit/Framework/TestSuite.php:473
PHP   9. Factory->__construct() /var/www/domain.tld/public_html/unittests/VisualPHPUnit/app/test/opencart/FW_OpenCartTest.php:41
PHP  10. trigger_error() /var/www/domain.tld/public_html/system/engine/factory.php:75

以下是导致错误的小测试:

<?php

require_once('FW_OpenCartTest.php');

class ControllerAccountWishListTest extends FWOpenCartTest {
    public function testTheContentsOfALoggedInCustomersWishList() {
        $controller = $this->loadControllerByRoute("account/wishlist");

            $this->customerLogin('username@domain.tld','9a24b01674');
            $controller->index();

            $this->assertEquals(1, preg_match('/Your wish list is empty./', $this->getOutput()));
    }
}

?>

我要求的是:这是PHPUnit和测试用例类FWOpenCartTest之间的交互吗?

完成的应用程序可以工作,如果我不使用PHPUnit但只是创建一个包装器来实例化测试它也可以工作。

如果存在交互,是否有任何方法可以隐藏stream_wrapper_register(),以便FWOpenCartTest的构造函数不会找到它已分配?

1 个答案:

答案 0 :(得分:1)

这就是我如何通过这种方式修复自己的个人情况。对于每个人来说,这并不意味着 THE

前提:我是怎么来到这里的

这个问题是我安装一个非常有用的OpenCart Testing Suite的结果。我喜欢它,因为如果你必须大量定制OpenCart,它将真正帮助控制整个项目。事实上,在定制这样一个大型MVC框架时,很容易造成意想不到的副作用。 这变得更加重要,因为OpenCart本身并不实现“零售开发者友好”的扩展/插件钩子,如WordPress或Drupal。 因此,大多数专业的OpenCart开发人员都会安装第三方扩展引擎,通常是VQMod和OpenCart Override Engine。

如何使测试工作

安装Testing Suite后,您将继承自己的OpenCart安装自定义。在我的情况下,单元测试适用于我自己的代码,所以我不需要1:1忠实的安装快照。在这方面我很幸运,因为Override Engine的工厂类与PHPUnit完全不兼容。两者都想使用var流,这会产生一个讨厌的冲突:甚至强迫PHPUnit和Override Engine使用相同的流,其中一个将调用不支持的函数并导致PHP错误。

因此我所做的就是

1)将我的Override Engine修改后的OpenCart安装的root index.php恢复为原始分发文件。但是我保留了自己的自定义。

以下屏幕截图显示了我查看两个index.php文件之间的差异。在左边是新版本,我正在“恢复”到原版,右边是当前安装的,基于工厂类的覆盖引擎版本。

编辑:遗憾的是我没有“rep”来放置图片here's the link

2)使用覆盖引擎修改更改已恢复的index.php。在我的情况下,我用我自己的版本替换了默认的缓存实例代码。基本上,您可以手动包含Override Engine目录中的文件,并将它们替换为默认类。

3)如果需要,你必须编写模拟对象/成员来运行测试套件。

如何运行OpenCart与PHPUnit兼容的代码示例,以便与Override Engine一起运行。

阶段1:在单元测试用例的index.php中找到覆盖引擎“已转换”代码:

// Cache
$cache = $factory->newCache();
$registry->set('cache', $cache);

阶段2:将单元测试用例的index.php语句恢复为原始OpenCart版本:

// Cache
$cache = new Cache();
$this->registry->set('cache', $cache);

阶段3:手动应用已覆盖的类和/或提供模拟对象

// Cache
// $cache = new Cache();
require_once (OVERRIDE_ENGINE_ROOT . 'mymods/system/library/cache.php');
$cache =  new MyMods_Custom_Cache();
$this->registry->set('cache', $cache);

尽可能接近完成解决方案。