【问题标题】: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();
          }
      }
      

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

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

      【讨论】:

        猜你喜欢
        • 2016-07-12
        • 1970-01-01
        • 2016-03-05
        • 2019-08-13
        • 2019-06-26
        • 2018-04-05
        • 2019-08-10
        • 2015-07-17
        • 2017-09-01
        相关资源
        最近更新 更多