嘲弄:模拟对象上不存在方法

Posted

技术标签:

【中文标题】嘲弄:模拟对象上不存在方法【英文标题】:Mockery: Method does not exist on mock object 【发布时间】:2016-07-12 11:08:04 【问题描述】:

所以我有一个我正在模拟的对象,它有用于发送电子邮件的方法。我已经从一个静态类转到了一个具体类,因为我在使用 Mockery 测试静态类时遇到了问题。

但是我现在发现,当一个 eloquent 模型被保存时,它会引发一个触发监听器的事件。这个监听器负责启动对模拟对象方法的调用。

我发现当我执行以下操作时,它会起作用。

$model = factory(MyClass::class)->make();
$model->property = 'value';
$model->save()
$this->mailer->shouldHaveReceived('methodName')->with($arg1, $arg2, $arg3);

每次抱怨模拟对象上不存在该方法时都会失败,最糟糕的是,如果我进入调用模拟对象方法的侦听器并执行类似的操作

echo '<pre>'.print_r(get_class_methods($this->mailer), true).'</pre>'; exit;

它表明该方法实际上在 get_class_methods 返回的方法数组中。

现在这是踢球者。如果我执行以下操作,一切都会完美运行,并且测试通过且没有任何错误:

$this->mailer->shouldReceive('methodName');
$model = factory(MyClass::class)->make();
$model->property = 'value';
$model->save()

现在我一直在阅读Mockery Gotchas,看来如果我的类正在通过___call 调用对象上真正不存在的方法,那么就会出现此错误。

但是,我的邮件程序类没有扩展任何其他具有__call 方法的类,也没有在该类上定义该方法。

但是,您可能知道也可能不知道 Eloquent 模型实际上使用了神奇的 ___call 方法。但是我不是用 Mockery 模拟模型,我在 Laravel 中使用工厂模型,但我也没有检查方法调用的模型对象,我正在检查我的具体邮件类以进行方法调用。

有人知道我为什么会从 Mockery 那里得到这种行为吗?

我正在使用以下代码在 Laravel 5.2 中创建我的模拟对象

public function mock($class)

    $mock = Mockery::mock($class);
    $this->app->instance($class, $mock);
    return $mock;


$this->mailer = $this->mock('Namespace\Classname');

【问题讨论】:

【参考方案1】:

你是如何创建$this-&gt;mailer 的?为了能够使用间谍功能-&gt;shouldHaveReceived,您需要在使用Mockery::mock($className) 创建测试替身后调用Mockery::spy($className) 或调用shouldIgnoreMissing 方法。

【讨论】:

我已经更新了我上面的帖子,以展示我是如何创建模拟对象的,尽管在研究这个问题时我没有看到任何关于 spy 方法的信息,我将不得不对此进行研究。除了我在上面发布的内容(已编辑)之外,我没有看到任何其他内容,即通过实例方法将模拟添加到 laravel 应用程序。 问题是该方法确实存在于模拟对象上,它说它不存在。

以上是关于嘲弄:模拟对象上不存在方法的主要内容,如果未能解决你的问题,请参考以下文章

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

“对象”类型上不存在属性“”。可观察订阅

Typescript Jest 说我想模拟的类型上不存在模拟或模拟返回值

嘲弄和method_exists

解决打字稿错误的最佳方法 - 类型上不存在属性

具有 API 29 的 Android 模拟器上不存在多显示选项