2012-08-26 89 views
2

我不知道我是否做错了什么,或者它是PHPUnit和模拟对象的错误。基本上我试图测试$Model->start()被触发时是否调用$Model->doSomething()PHPUnit和模拟对象不工作

我在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. 
+0

我得到它的工作,但我不得不作为一个数组传递的方法。 'code' $ Model = $ this-> getMock('Model',array('doSomething','doNothing')); ($ this-> once()) - > method('start'); #这工作 – James

+0

有谁知道你为什么必须指定方法。这是一个配置问题。许多使用mock的例子并没有说明你必须指定方法。 – James

+0

你真的指的是phpUnit 1.1.1吗?最新版本是3.7,最早可能在受支持的Linux发行版中遇到的是phpUnit 3.4左右。 –

回答

3

当你发现,你需要告诉PHPUnit的嘲弄哪些方法。另外,我会避免为您直接从测试中调用的方法创建期望值。我会写这样上面的测试:

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

只是为了扩大为什么大卫·哈克尼斯的答复工作,如果你不指定$方法参数getMock然后类中的所有功能嘲笑。顺便提一句,你可以用下面的方法确认:

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

那么,它为什么会失败?因为你的start()功能也被嘲笑!即您提供的功能体已被替换,因此您的$this->doSomething();行永远不会运行。

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