【问题标题】:PHPunit: Can I mock class that I test?PHPunit:我可以模拟我测试的类吗?
【发布时间】:2018-12-27 17:39:52
【问题描述】:

我有这样的课:

<?php
class Apple { 
    public function foo($arg1){
        if ($arg1 == 0){
            $this->bar($arg1);
        }
    }

    public function bar($arg){
        //do something
    }
}

我有一个这样的单元测试:

class AppleTest extends TestCase{
    /**
     * it's unit test for method Apple::foo
     */
    public function testFoo(){
        $mock = $this->getMockBuilder('Apple')
            ->setMethods(['bar'])
            ->getMock();

        $mock->expects($this->once())
            ->method('bar')
            ->with($this->equalTo(0));

        $mock->foo(0);
    }
}

有人告诉我,我不能对正在测试的课程使用模拟。我被告知我应该使用类的实例而不是它的模拟,因为当我使用模拟时它不是实际测试。有人可以对此提出异议吗?

【问题讨论】:

  • Mocking 用于外部依赖。模拟您正在测试的类是没有意义的,因为除了您编写的单元测试代码之外,您实际上不会测试任何东西。

标签: php unit-testing testing phpunit


【解决方案1】:

不是你“不能”,而是你真的不应该。显然,从您的示例测试中,您可以模拟您正在测试的对象。

但这不一定是个好主意。这样做的问题是您要准确指定代码的外观。这会使重构更加困难。假设bar 函数需要更改,并且您想将foo 需要的功能移动到私有函数中。现在您的测试将失败,因为foo 不再调用bar。在这种情况下,它应该通过,因为功能没有改变。这是单元测试的一大好处,您可以重构代码并确保一切正常。

但是,有时需要模拟您正在测试的类。通常这是当您尝试为现有代码编写新测试并且您无法重构它以使用依赖注入时。然后,您将不得不模拟其他功能以隔离事物。这并不理想,应该避免,但编写一个“糟糕”的测试总比没有测试要好。

【讨论】:

    猜你喜欢
    • 2013-09-29
    • 2012-07-02
    • 1970-01-01
    • 2019-12-14
    • 2018-04-19
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多