PHPUnit:是否可以模拟一个php函数来返回一个模拟对象来代替普通对象?

时间:2016-09-14 19:01:49

标签: php unit-testing testing mocking phpunit

我在类someClass中有一个构造函数,它调用一个函数(initObjectFunc),它的唯一目的是返回一个新创建的Thing类实例,并将它的对象放入构造函数中的一个属性(thingObject)。 / p>

class someClass {
    public function __construct() {
        $this->thingObject = $this->initObjectFunc();
    }

    function initObjectFunc() {
        return new Thing();
    }
}

class Thing {
    public function __construct() {}

    function funcB() {
        ... funcB normal implementation ...
        return value;
    }
}

我还有一个单独的函数(funcA),也在someClass类中,它使用thingObject来调用它的内部函数(funcB)。

 .
 .
 .

function funcA() {
    $data = $this->thingObject->funcB();
    ... other stuff ....
}

在PHPUnit测试类中,我通过执行funcA来模拟Thing类及其funcB来返回模拟数据('测试测试测试')。为了将所有部分连接在一起,我模拟了initObjectFunc以返回该模拟的Thing类对象。

class unitTest extends PHPUnit_Framework_TestCase {

$mockThing = $this->getMockBuilder('Thing')
    ->setMethods(array('funcB'))
    ->getMock()
    ->expects($this->any())
    ->method('funcB')
    ->will($this->returnValue('test test test test'));

$mockSomeClass = $this->getMockBuilder('someClass')
    ->setMethods(array('initObjectFunc'))
    ->getMock()
    ->expects($this->any())
    ->method('initObjectFunc')
    ->will($this->returnValue($mockThing));

}

此设置是在记住此执行流程的情况下创建的:

$mockSomeClass calls-> funcA() calls-> *mocked*funcB through *mocked*Thing class

使用$ mockSomeClass来调用funcA(在PHPUnit中,它不应该被存根并且应该具有完整的功能),这将调用funcB。但是,因为我嘲笑Thing类及其funcB,所以应该调用模拟的funcB来返回测试测试测试'。

当我尝试运行测试时,情况并非如此。它打破没有任何错误。甚至没有说明有多少测试,断言,跳过,和失败了。

我也曾尝试过这种变化,但无济于事:

class someClass {
    public function __construct() {}

    function initObjectFunc() {
        return new Thing();
    }

    function funcA() {
        $thingObject = initObjectFunc();
        $data = $thingObject->funcB();
        ... other stuff ....
    }
}

此变体尝试从构造函数中获取功能并将其移动到funcA中,以便调用initObjectFunc()并在使用它调用funcB之前返回一个模拟的Thing实例。这是在想到可以在任何模拟之前调用someClass构造函数的情况下完成的。

我不知道这些组件为何或如何不连接。有没有人尝试过这种结构的单元测试并取得了成功?我知道一个简单的代码重构成为"依赖注入" -friendly会解决这个问题,但这是一个问题,只是为了找出这个单元测试的路径是否有效。

0 个答案:

没有答案