PHPUnit 模拟对象和方法类型提示

Posted

技术标签:

【中文标题】PHPUnit 模拟对象和方法类型提示【英文标题】:PHPUnit mock objects and method type hinting 【发布时间】:2011-03-14 09:47:01 【问题描述】:

我正在尝试使用 phpunit 创建 \SplObserver 的模拟对象,并将模拟对象附加到 \SplSubject。当我尝试将模拟对象附加到实现 \SplSubject 的类时,我收到一个可捕获的致命错误,指出模拟对象未实现 \SplObserver:

PHP Catchable fatal error:  Argument 1 passed to ..\AbstractSubject::attach() must implement interface SplObserver, instance of PHPUnit_Framework_MockObject_Builder_InvocationMocker given, called in ../Decorator/ResultCacheTest.php on line 44 and defined in /users/.../AbstractSubject.php on line 49

或多或少,这里是代码:

// Edit: Using the fully qualified name doesn't work either
$observer = $this->getMock('SplObserver', array('update'))
    ->expects($this->once())
    ->method('update');

// Attach the mock object to the cache object and listen for the results to be set on cache
$this->_cache->attach($observer);

doSomethingThatSetsCache();

我不确定这是否会有所不同,但我使用的是 PHP 5.3 和 PHPUnit 3.4.9

【问题讨论】:

【参考方案1】:

更新

哦,实际上,问题很简单,但不知何故很难发现。而不是:

$observer = $this->getMock('SplObserver', array('update'))
                 ->expects($this->once())
                 ->method('update');

你必须写:

$observer = $this->getMock('SplObserver', array('update'));
$observer->expects($this->once())
         ->method('update');

这是因为 getMock() 返回的内容与 method() 不同,这就是您收到错误的原因。您将错误的对象传递给attach

原答案

我认为你必须完全限定模拟的类型:

$observer = $this->getMock('\SplObserver', array('update'));

【讨论】:

是的!就是这样——我试图让流畅的界面变得过于聪明。感谢您的帮助! 为了清楚起见,该类确实必须是完全限定的除了单独调用expects()。

以上是关于PHPUnit 模拟对象和方法类型提示的主要内容,如果未能解决你的问题,请参考以下文章

PHPUnit 模拟对象类型

PHPUnit 模拟一个抽象类的所有方法

在 PHPUnit 中实现给定接口的模拟对象上的未定义方法?

使用 PHPUnit 模拟 PDO 对象

PhpStorm 配置 PHPUnit

是否有可能使用 PHPUnit 模拟对象来调用一个神奇的 __call() 方法?