模拟正在测试或测试实例的服务


Mocking the service that is tested or test an instance

我最终与我的一位同事讨论了如何设置用于测试服务类的单元测试。

在设置测试用例时,我们中的一个建议模拟我们正在测试的实际类,而另一个则更喜欢创建该类的实例,只模拟依赖关系。

假设我们正在测试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
    }
}