phpunit mock不返回赋值

时间:2014-05-22 11:34:41

标签: mocking phpunit

我有这段代码:

class TestMe {
    private $params;

    public function __construct($params) {
        $this->params = $params;
    }

    public function one($arg) {
        echo 'one is running ';
        $next = $arg + 1;
        return $this->two($next);
    }

    private function two($arg) {
        echo 'two is running ';
        $next = $arg + 1;
        return $this->three($next);
    }

    private function three($arg) {
        echo 'three is running ';
        return 'original return value';
    }
}

class TestMeTest extends PHPUnit_Framework_TestCase {
    private $params = array();

    public function test() {
        $testMeMock = $this->getMockBuilder('TestMe')
            ->setConstructorArgs( array($this->params) )
            ->setMethods( array('two') )
            ->getMock();

        $testMeMock->expects($this->any())
                ->method('two')
                ->will($this->returnArgument(0));

        $result = $testMeMock->one(1);

        $this->assertEquals(2, $result);
    }
}

我写这个是为了测试进入方法'two'的参数,但是我得到'原始返回值'字符串,并且'三'方法正在运行。

Failed asserting that 'original return value' matches expected 2.

我如何测试以验证进入'two'的参数?

1 个答案:

答案 0 :(得分:1)

您的问题是您尝试模拟的函数是private,并且您的模拟调用原始函数而不是模拟替换。将功能更改为protected,您的测试将按预期运行。

另外,通常不建议测试类的protected / private方法。通常,您应该只测试类的公共接口。如果内部方法足够复杂,需要进行模拟,则表明您可能希望将这些方法重构为自己的类。

http://sebastian-bergmann.de/archives/881-Testing-Your-Privates.html

这有效:

class TestMe {
    private $params;

    public function __construct($params) {
        $this->params = $params;
    }

    public function one($arg) {
        echo 'one is running ';
        $next = $arg + 1;
        return $this->two($next);
    }

    protected function two($arg) {
        echo 'two is running ';
        $next = $arg + 1;
        return $this->three($next);
    }

    private function three($arg) {
        echo 'three is running ';
        return 'original return value';
    }
}

class TestMeTest extends PHPUnit_Framework_TestCase {
    private $params = array();

    public function test() {
        $testMeMock = $this->getMockBuilder('TestMe')
            ->setConstructorArgs( array($this->params) )
            ->setMethods( array('two') )
            ->getMock();

        $testMeMock->expects($this->any())
                ->method('two')
                ->will($this->returnArgument(0));

        $result = $testMeMock->one(1);

        $this->assertEquals(2, $result);
    }
}