【问题标题】:Mockery: BadMethodCallException: Method Mockery_0_Foo::bar() does not exist on this mock object嘲弄:BadMethodCallException:此模拟对象上不存在方法 Mockery_0_Foo::bar()
【发布时间】:2015-11-13 00:36:14
【问题描述】:
我无法让 Mockery 创建一个简单的假人:
<?php
require_once '../vendor/autoload.php'; // composer autoload mockery
class Foo {
private $required;
public function __construct($required){
$this->required = $required;
}
public function bar(){
// do stuff with $this->required
}
}
class FooTest extends PHPUnit_Framework_TestCase {
public function testBar(){
$mock = \Mockery::mock('\Foo');
$mock->bar();
}
}
运行 PHPUnit 测试会报错:
BadMethodCallException: Method Mockery_0_Foo::bar() does not exist on this mock object
我做错了什么?
【问题讨论】:
标签:
php
phpunit
composer-php
mockery
【解决方案1】:
如果您想对“Foo”类进行 php 单元测试并模拟“Required”对象。只需像下面这样:
class Foo {
private $required;
public function __construct(\Required $required){
$this->required = $required;
}
public function bar(){
return $this->required->getTextFromBarTable();
}
}
class FooTest extends PHPUnit_Framework_TestCase {
public function testBar(){
$mock = \Mockery::mock('\Required'); // Dummy, There are no properties or methods.
/**
* Stub "getTextFromBarTable" method of \Required class
* and fakes response by returning "return this text".
*/
$mock->shouldReceive('getTextFromBarTable')
->andReturn('return this text');
// create "Foo" Object by using $mock instead of actual "\Required" Object.
$foo = new Foo($mock);
$response = $foo->bar();
$this->assertEqual('return this text', $response);
}
}
您不得存根或模拟您要对其进行单元测试的类。只需在“\Required”之类的依赖类上执行此操作即可。
我们使用 STUB 或 MOCK 来分离可能影响我们要测试的方法的内部逻辑的外部逻辑。在这种情况下,我假设 \Required 类具有“getTextFromBarTable”方法,并且该方法将连接并从数据库中获取“文本”字段。如果我们的数据库没有文本字段,“testBar”方法将被破坏。为了摆脱外部问题,我在“\Required”上做了存根,每次我使用“getTextFromBarTable”方法。它总是会返回“返回此文本”。
【解决方案2】:
我必须明确说明模拟生成的存根方法:
class FooTest extends PHPUnit_Framework_TestCase {
public function testBar(){
$mock = \Mockery::mock('Foo');
$mock->shouldReceive('bar');
$mock->bar();
}
}
我很好奇是否有办法解决这个问题,或者:
- 隐式捕获在
Foo 中定义的所有方法调用,或者
- 隐式捕获所有方法调用,无论它们是否在
Foo 中定义