我正在用PHPUnit在现有的代码库上实现单元测试。我对单元测试相当陌生,但我知道一个目标是完全隔离正在测试的代码。这在我的代码库中被证明是困难的,因为许多类依赖于代码库中的其他类。
依赖项是硬编码到类中的,因此无法使用依赖项注入。我也不想仅仅为了测试而重构现有的代码。因此,为了将每个类与其依赖项隔离开来,我创建了一个“模拟”类库(不是通过使用PHPUnit的模拟框架,而是通过创建一个包含存根函数的类库,这些存根函数根据特定的输入返回我期望的结果)。
问题是,如果在phpunit运行期间,我有一个调用mock类的测试,然后我尝试测试实际的类,我会得到一个致命的错误,因为PHP认为这是在重新声明类。这是我所说的一个简化的例子。请注意,即使我取消设置已包含的类的所有实例并清除tearDown方法中的包含路径,此操作仍会失败。再说一次,我是个单元测试新手,所以如果我做错了或者遗漏了一些明显的东西,请让我知道。
一个更大的问题可能是,这种方法是否会在隔离代码的方向上走得太远,以及使用真实对象作为类的依赖项是否真的有好处。
#### real A
require_once 'b.class.php';
class A {
private $b;
public function __construct() {
$this->b = new B();
}
public function myMethod($foo) {
return $this->b->exampleMethod($foo);
}
}
#### real B
class B {
public function exampleMethod($foo) {
return $foo . "bar";
}
}
#### mock B
class B {
public function exampleMethod($foo) {
switch($foo) {
case 'test':
return 'testbar';
default:
throw new Exception('Unexpected input for stub function ' . __FUNCTION__);
}
}
}
#### test A
class TestA extends PHPUnit_Extensions_Database_TestCase {
protected function setUp()
{
// include mocks specific to this test
set_include_path(get_include_path() . PATH_SEPARATOR . 'tests/A/mocks');
// require the class we are testing
require_once 'a.class.php';
$this->a = new A();
}
public function testMyMethod() {
$this->assertEquals('testbar', $a->myMethod('test'));
}
}
#### test B
class TestB extends PHPUnit_Extensions_Database_TestCase {
protected function setUp()
{
// include mocks specific to this test
set_include_path(get_include_path() . PATH_SEPARATOR . 'tests/B/mocks');
// require the class we are testing
// THIS FAILS WITH: 'PHP Fatal error: Cannot redeclare class B'
require_once 'b.class.php';
$this->b = new AB();
}
}发布于 2012-03-24 11:32:01
我认为您需要在隔离的进程中运行测试。
要么为执行测试提供一个参数:"--process-isolation“,要么设置$this->processIsolation = true;
发布于 2012-03-24 21:03:50
如果您由于某些原因(有一些有效的原因)不能使用PHPUnit模拟API (或模拟),那么您需要自己创建模拟类。
模拟类应该与真实类具有相同的" type“(以便类型提示仍然有效),因此您应该扩展真实类:
#### mock B
class Mock_B extends B {这也解决了在PHP中不能有两个同名的类的问题:)
发布于 2012-03-26 23:20:58
在声明mock时,也可以使用命名空间。
https://stackoverflow.com/questions/9847920
复制相似问题