类似的问题已在这里被问过多次
- PHPUnit loads all classes at once. Causes PHP Fatal error: Cannot redeclare class
- Cannot redeclare class error when generating PHPUnit code coverage report
PHPUnit 触发新的 fatal error
Fatal error: Cannot redeclare class Validator in /some/path/to/Validator.php on line 6
ValidatorTest
类
class ValidatorTest extends PHPUnit_Framework_TestCase
{
/**
* @dataProvider data_provider_rules
*/
public function test_factory($rules)
{
define('DIR_SEP', DIRECTORY_SEPARATOR);
define('SYS_DIR', '.'.DIR_SEP.'..'.DIR_SEP.'classes'); //relative path here
require SYS_DIR.DIR_SEP.'Validator.php';
$validator = Validator::factory();
return $validator;
}
}
以及Validator
类
class Validator
{
private static $validator = FALSE;
public function __construct()
{
}
public static function factory()
{
if (empty(self::$validator))
{
self::$validator = new Validator();
}
return self::$validator;
}
}
这些类很简单,没有自动加载或包含/需要任何内容。我正在从单独的测试目录运行测试,该目录仅包含 ValidatorTest.php
和配置文件 phpunit.xml
(从 here 复制)。测试运行良好时
processIsolation="true"
当使用 require_once
而不是 require
时,测试也可以工作。 所以我的问题是哪个(如果有)以及为什么:我是否必须显式地将 processIsolation
属性设置为 true
(因为默认值为 false),使用 require_once
(感觉不是最好的解决方案)或重构代码(停止使用静态作用域、相对路径等)?
最佳答案
您正在使用 dataProvider
,因此我们假设 test_factory
方法被调用多次。
在此方法中,您有一个 require
句子。这将产生您在测试内部或外部遇到的错误。
这与您编写的内容相同:
require SYS_DIR.DIR_SEP.'Validator.php';
require SYS_DIR.DIR_SEP.'Validator.php';
解决方案是增强您设置测试的方式:
根据定义,测试的前 3 行应该只执行一次,因此将它们放入 setUpBeforeClass 中:
class ValidatorTest extends PHPUnit_Framework_TestCase
{
public static function setUpBeforeClass()
{
define('DIR_SEP', DIRECTORY_SEPARATOR);
define('SYS_DIR', '.'.DIR_SEP.'..'.DIR_SEP.'classes'); //relative path here
require SYS_DIR.DIR_SEP.'Validator.php';
}
/**
* @dataProvider data_provider_rules
*/
public function test_factory($rules)
{
$validator = Validator::factory();
return $validator;
}
}
无论如何,IMO 在测试中使用 require_once
并检查常量是否已经定义是没问题的。
关于PHPUnit - 当 processIsolation 设置为 false 时无法重新声明类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30049347/