Mockery:BadMethodCallException:方法Mockery_0_Foo :: bar()在此模拟对象上不存在

时间:2015-08-19 15:43:17

标签: php phpunit composer-php mockery

我无法让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

我做错了什么?

2 个答案:

答案 0 :(得分:3)

如果您想在“Foo”类上进行php单元测试并模拟“必需”对象。就像下面这样做:

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来分隔可能影响我们要测试的方法的INTERNAL逻辑的EXTERNAL逻辑。在这种情况下,我假设\ Required类具有“getTextFromBarTable”方法,此方法将连接并从数据库中获取“text”字段。如果我们的数据库没有文本字段,那么“testBar”方法将被破坏。为了摆脱外部问题,我在“\ Required”上存根,每次都使用“getTextFromBarTable”方法。它总会让我“回复此文本”。

答案 1 :(得分:1)

我必须明确说明mock使用什么方法创建存根:

class FooTest extends PHPUnit_Framework_TestCase  {
    public function testBar(){
        $mock = \Mockery::mock('Foo');
        $mock->shouldReceive('bar');
        $mock->bar();
    }
}

我很好奇是否有办法解决这个问题:

  1. 隐式捕获Foo
  2. 中定义的所有方法调用
  3. 隐式捕获所有方法调用,无论它们是否在Foo
  4. 中定义