PHPUnit和Mock对象无法正常工作

3

我不确定是我做错了什么还是PHPUnit和模拟对象的一个bug。基本上,我正在尝试测试当触发$Model->start()时是否调用了$Model->doSomething()

我在VirtualBox中使用Ubuntu,并通过pear安装了phpunit 1.1.1。

完整代码如下。任何帮助都将不胜感激,这让我发疯了。

<?php
require_once 'PHPUnit/Autoload.php';

class Model
{
    function doSomething( ) {
        echo 'Hello World';
    }

    function doNothing( ) { }

    function start( ) {
        $this->doNothing();
        $this->doSomething();
    }
}

class ModelTest extends PHPUnit_Framework_TestCase
{
    function testDoSomething( )
    {
        $Model = $this->getMock('Model');
        $Model->expects($this->once())->method('start'); # This works
        $Model->expects($this->once())->method('doSomething'); # This does not work
        $Model->start();
    }
}
?>

PHPUnit 的输出:

There was 1 failure:

1) ModelTest::testDoSomething
Expectation failed for method name is equal to <string:doSomething> when invoked 1 time(s).
Method was expected to be called 1 times, actually called 0 times.


FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

我已经解决了,但是我不得不将方法作为一个数组传递。 code $Model = $this->getMock('Model',array('doSomething','doNothing')); #$Model->expects($this->once())->method('start'); # 这个方法有效 - undefined
有人知道为什么必须指定方法吗?这是一个配置问题吗?很多使用模拟对象的示例并没有说明必须指定方法。 - undefined
你真的是指 phpUnit 1.1.1 吗?最新版本是3.7,而在支持的 Linux 发行版中你可能遇到的最早版本大约是 phpUnit 3.4。 - undefined
抱歉,我的错,不确定我从哪里得到了1.1.1版本,我正在使用的是3.6.12版本。感谢大家的帮助。 - undefined
2个回答

3

正如您所发现的,您需要告诉PHPUnit哪些方法需要进行模拟。此外,我建议避免为测试中直接调用的方法创建期望。我会这样编写上面的测试:

function testDoSomething( )
{
    $Model = $this->getMock('Model', array('doSomething');
    $Model->expects($this->once())->method('doSomething');
    $Model->start();
}

0
只是为了进一步解释为什么David Harkness的答案有效,如果您不指定$methods参数给getMock函数,那么类中的所有函数都会被模拟。顺便说一句,您可以通过以下方式确认这一点:
class ModelTest extends PHPUnit_Framework_TestCase
{
    function testDoSomething( )
    {
        $obj = $this->getMock('Model');
        echo new ReflectionClass(get_class($obj));
        ...
    }
}

所以,为什么会失败呢?因为你的start()函数也被模拟了!也就是说,你给出的函数体已经被替换掉了,所以你的$this->doSomething();这一行代码根本没有执行。
因此,当你的类中有任何需要保留的函数时,你都需要明确列出所有其他函数的列表。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接