Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/249.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHPUnit:是否可以模拟php函数以返回模拟对象来替换普通对象?_Php_Unit Testing_Testing_Mocking_Phpunit - Fatal编程技术网

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

PHPUnit:是否可以模拟php函数以返回模拟对象来替换普通对象?,php,unit-testing,testing,mocking,phpunit,Php,Unit Testing,Testing,Mocking,Phpunit,我在类someClass中有一个构造函数,它调用一个函数(initObjectFunc),它的唯一目的是返回一个新创建的Thing类实例,并将其对象放入构造函数中的属性(thingObject)中 class someClass { public function __construct() { $this->thingObject = $this->initObjectFunc(); } function initObjectFunc()

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

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)

在PHPUnit测试类中,我模拟了Thing类及其funcB,以便在通过执行funcA调用它时返回模拟数据(“test”)。为了将所有部分连接在一起,我模拟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中,funcA不应该被存根,应该具有完整的功能),funcA将调用funcB。然而,由于我模拟了Thing类及其funcB,它应该调用模拟的funcB以返回“test”

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

我也尝试过这种变化,但没有效果:

class someClass {
    public function __construct() {}

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

    function funcA() {
        $thingObject = initObjectFunc();
        $data = $thingObject->funcB();
        ... other stuff ....
    }
}
此变体尝试从构造函数中获取功能并将其移动到funcA中,以便调用initObjectFunc(),并在使用它调用funcB之前返回模拟对象实例。这是在这样的思想下完成的,即可能在进行任何模拟之前调用someClass构造函数

我不知道这些组件为什么或如何不连接。有没有人尝试过使用这种结构进行单元测试并取得成功?我知道,一个简单的代码重构,使之成为“依赖注入”友好型,就可以解决这个问题,但这是一个问题,只是为了找出这条通向单元测试的道路是否可行

class someClass {
    public function __construct() {}

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

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