如何模拟在测试类中创建的类?

时间:2015-01-06 17:05:24

标签: php unit-testing phpunit

在PHPUnit文档中,处理模拟的部分解释了如何在测试类中附加模拟对象:

...
$observer = $this->getMockBuilder('Observer')
                 ->setMethods(array('update'))
                 ->getMock();
...
$subject = new Subject('My subject');
$subject->attach($observer);
$subject->doSomething();

就我而言,我想测试Subject方法。这个方法创建了许多这样的对象:

public function myMethod() {
    for($i = 0; $i < 10; $i++) {
        $this->collection []= new Observer(/* some data */);
    }
}

我如何模仿所有观察者?

1 个答案:

答案 0 :(得分:1)

你不能嘲笑这门课。 new运算符将根据您的自动加载器或已经存储的内容获取类的定义。您无法在测试中动态替换类定义。

您可以为Observer创建一个具有已定义行为的备用类定义,并且本质上是您将使用的“模拟”类。这样做的问题是,如果您使用实际Observer类的测试运行此测试,您将最终得到一个错误,您无法重新定义该类。事情变得非常复杂。

您的示例非常简单,但我会通过确保Subject::collection中的所有元素都是Observer的实例来验证它。如果我知道每个观察者的任何具体数据,那么我会使用实际的Observer方法来验证它们。 (虽然这不是一个好习惯)。

如果您的方法正在创建对象然后调用它们的方法,我会认真重新考虑您的设计。我会将myMethod分解成至少两种方法。附加一个Observer对象的对象,您可以在测试中使用该对象来传递模拟对象。另一个调用Observer的方法,它们是你没有的myMethod函数的其余部分。