【问题标题】:PHPUnit and Mock Objects not workingPHPUnit 和模拟对象不起作用
【发布时间】:2012-08-21 07:40:23
【问题描述】:

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

我在 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'); # 这行得通
  • 有谁知道你为什么必须指定方法。这是配置问题吗。许多使用模拟的示例并未说明您必须指定方法。
  • 你真的是说 phpUnit 1.1.1 吗?最新的是 3.7,在受支持的 linux 发行版中您可能遇到的最早是 phpUnit 3.4 左右。
  • 对不起,我不确定我从哪里得到 1.1.1,我使用的是 3.6.12 版本。感谢大家的帮助。

标签: php object mocking phpunit stubs


【解决方案1】:

正如您所发现的,您需要告诉 PHPUnit 要模拟哪些方法。另外,我会避免对您直接从测试中调用的方法产生期望。我会这样写上面的测试:

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

【讨论】:

    【解决方案2】:

    只是为了扩展 David Harkness 的答案为何有效,如果您没有为 getMock 指定 $methods 参数,那么类中的 所有 函数都会被模拟。顺便说一句,您可以通过以下方式确认:

    class ModelTest extends PHPUnit_Framework_TestCase
    {
        function testDoSomething( )
        {
            $obj = $this->getMock('Model');
            echo new ReflectionClass(get_class($obj));
            ...
        }
    }
    

    那么,为什么会失败?因为你的 start() 函数也被嘲笑了! IE。您提供的函数体已被替换,因此您的 $this-&gt;doSomething(); 行永远不会运行。

    因此,当您的类中有任何函数需要保留时,您必须明确给出所有其他函数的列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-27
      • 2011-03-09
      • 2019-08-10
      • 1970-01-01
      • 2021-10-31
      • 2012-09-26
      相关资源
      最近更新 更多