PHPUnit - 当 processIsolation 设置为 false 时无法重新声明 class
PHPUnit - Cannot redeclare class when processIsolation set to false
类似的问题已经被问过好几次了
- 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: Cannot redeclare class Validator in /some/path/to/Validator.php on line 6
ValidatorTest
class
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
class Validator
{
private static $validator = FALSE;
public function __construct()
{
}
public static function factory()
{
if (empty(self::$validator))
{
self::$validator = new Validator();
}
return self::$validator;
}
}
classes 是微不足道的,没有任何自动加载或 include/require。我正在 运行 从仅包含 ValidatorTest.php
和配置文件 phpunit.xml
(从 here 复制)的单独测试目录中进行测试。当
时,测试 运行 正常
processIsolation="true"
当使用 require_once
而不是 require
时,测试也有效。 所以我的问题是哪个(如果有的话)和为什么:我是否必须明确地将 processIsolation
属性设置为 true
(因为默认值为 false),使用 require_once
(感觉不是最佳解决方案)或重构代码(停止使用静态作用域、相对路径等)?
您必须在测试之前使用 PHPUnit 注释
/**
* @preserveGlobalState
* @runTestsInSeparateProcesses
*/
class ValidatorTest extends PHPUnit_Framework_TestCase
{
...
}
或者,您可以在特定测试之上使用@runInSeparateProcess 而不是@runTestsInSeparateProcesses。
您正在使用 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 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: Cannot redeclare class Validator in /some/path/to/Validator.php on line 6
ValidatorTest
class
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
class Validator
{
private static $validator = FALSE;
public function __construct()
{
}
public static function factory()
{
if (empty(self::$validator))
{
self::$validator = new Validator();
}
return self::$validator;
}
}
classes 是微不足道的,没有任何自动加载或 include/require。我正在 运行 从仅包含 ValidatorTest.php
和配置文件 phpunit.xml
(从 here 复制)的单独测试目录中进行测试。当
processIsolation="true"
当使用 require_once
而不是 require
时,测试也有效。 所以我的问题是哪个(如果有的话)和为什么:我是否必须明确地将 processIsolation
属性设置为 true
(因为默认值为 false),使用 require_once
(感觉不是最佳解决方案)或重构代码(停止使用静态作用域、相对路径等)?
您必须在测试之前使用 PHPUnit 注释
/**
* @preserveGlobalState
* @runTestsInSeparateProcesses
*/
class ValidatorTest extends PHPUnit_Framework_TestCase
{
...
}
或者,您可以在特定测试之上使用@runInSeparateProcess 而不是@runTestsInSeparateProcesses。
您正在使用 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
并检查常量是否已经定义在测试中是好的。