我最终与我的一位同事讨论了如何设置用于测试服务类的单元测试。
在设置测试用例时,我们中的一个建议模拟我们正在测试的实际类,而另一个则更喜欢创建该类的实例,只模拟依赖关系。
假设我们正在测试SomeService
一种解决方案是模拟实际服务并测试模拟:
$firstDependency = //create mock for first dependency
$secondDependency = //create mock for second dependency
$this->someService = $this->getMockBuilder(SomeService::class)
->setMethods(null)
->setConstructorArgs(array($firstDependency, $secondDependency))
->getMock();
// continue testing $this->someService which is a mock
另一种解决方案是测试服务实例,只模拟依赖关系:
$firstDependency = //create mock for first dependency
$secondDependency = //create mock for second dependency
$this->someService= new SomeService($firstDependency, $secondDependency);
// continue testing $this->someService which is direct instance of SomeService
以下哪种解决方案被视为最佳实践?
答案最好参考官方php单元文档或其他可靠来源。
不要模拟测试中的类。不完全是php单元文档,但所有要点仍然有效。模拟SUT最终测试的是模拟,而不是将在生产中使用的实际类。
单元测试的目的是测试行为。嘲笑你想要测试的对象实际上意味着你在测试"伪造"的行为。测试预先定义的行为有什么意义?
在测试抽象类的情况下,创建mock被认为是一种良好的做法:
class AbstractClassTest extends PHPUnit_Framework_TestCase
{
/**
* Service under test in this case an abstract class
*/
$this->sut;
public function setUp()
{
$this->sut = $this->getMockForAbstractClass('My'Abstract'Class');
}
public function testMyAbstractClass()
{
$this->sut // do your test
}
}