我认为单元测试非常生疏。
我在Registration.php中有以下功能:
protected function _showModal($request) {
if (Store::isUserSupported()) {
return false;
}
return true;
}
我开始编写以下测试,但我知道我缺少一些关键项目:
public function testUserSupported() {
$mockStore = $this->getMockClass('Store', array('isUserSupported'));
$mockStore::staticExpects($this->once())
->method('isUserSupported')
->will($this->returnValue(true));
$mockStore::isUserSupported();
$plugin = $this->getMockBuilder('Registration')
->setMethods(array('_showModal'))
->disableOriginalConstructor()
->getMock();
$plugin = $this->getPublicClass($plugin);
$plugin->expects($this->once())
->method('_showTermsModal')
->will($this->returnValue(true));
}
$ mockStore部分被调用,但不知道如何将它绑定到我的$ plugin调用..我想编写一个测试来模拟Store :: isUserSupported()在showModal函数中返回true。有任何建议吗?
答案 0 :(得分:2)
您应该避免代码中的静态调用,因为它们会使您的代码耦合在一起,难以更改并且难以维护。这也使得测试变得更加困难,因为你在这里受苦。
而不是静态调用,传递工作所需的协作者。在您的代码示例中,您要测试的类将作为Store类的参数接收,而不是静态调用它。
通过执行此更改,您现在可以为Store类的方法isUserSupported()创建一个模拟,并将模拟传递给正在测试的对象,这将有效地使用模拟对象。
$mockStore = $this->getMock('Store', array('isUserSupported'));
$mockStore->expects($this->once())
->method('isUserSupported')
->will($this->returnValue(true));
$object_under_test = new Registration( $mockStore );
$object_under_test->showModal($request); // Only in case showModal is public, otherwise call public method
如果只有该方法需要Store类,并且您不想在构造函数中将其作为依赖项传递,则可以在方法本身上传递它。
$mockStore = $this->getMock('Store', array('isUserSupported'));
$mockStore->expects($this->once())
->method('isUserSupported')
->will($this->returnValue(true));
$object_under_test = new Registration();
$object_under_test->showModal($mockStore, $request); // Only in case showModal is public, otherwise call public method
此外,您不应该测试类的protected / private方法,因为它们是您的测试不需要了解的低级实现细节。您应该只在测试中调用公共方法。否则,测试将与实际实现非常相关,如果您重构代码,您很可能也必须更改测试。