嘲弄和method_exists

Posted

技术标签:

【中文标题】嘲弄和method_exists【英文标题】:Mockery and method_exists 【发布时间】:2018-12-24 04:21:56 【问题描述】:

我需要用 Mockery 模拟一个模拟类的方法的存在,但是当我使用 method_exists 检查时,我得到了一个错误的结果:

$mock = m::mock('ClassA')->makePartial();
$mock->shouldReceive('getMethod')->andReturn('A');
var_dump(method_exists($mock, 'getMethod'));

结果:

bool(false)

如何让它发挥作用?

【问题讨论】:

【参考方案1】:

getMethod 不能存在于 ClassA 中,否则 method_exists 会失败。

在模拟现有类时,method_exists 将为该类中实际存在的任何方法返回 true。

当方法不存在时,由于shouldReceive实际上不会定义方法而是使用重载(__call),所以还是会返回false。

【讨论】:

确实如此。那么,如何检查一个 mocked 方法的存在呢? 为什么要模拟一个不存在的方法? 方法存在但类是存根。 看来您应该将该方法添加到存根中。您可以使用 is_callable ,但这将在任何模拟上返回 true。 是的。 is_callable 总是返回 true。【参考方案2】:

您可以为被测类的命名空间覆盖method_exists 函数...

下面的代码进入测试用例文件...

// someTest.php

namespace App\Class\Under\Test\Namespace;

function method_exists($object, $method_name) 

    if ($method_name == 'getMethod') 
        return true;
    
    return \method_exists($object, $method_name);
;

【讨论】:

以上是关于嘲弄和method_exists的主要内容,如果未能解决你的问题,请参考以下文章

用嘲弄来嘲弄 trait 方法

嘲弄“应该接收”但方法不存在

未找到“嘲弄”类

嘲弄:被动部分模拟与默认模拟有何不同?

在控制器中的自定义类上调用 0 次嘲弄模拟和间谍

ES6类开玩笑嘲弄