Mockery 无法使用 Eloquent 模型填充方法创建部分模拟

Posted

技术标签:

【中文标题】Mockery 无法使用 Eloquent 模型填充方法创建部分模拟【英文标题】:Mockery cannot create a partial mock with Eloquent Model fill method 【发布时间】:2015-12-23 19:13:28 【问题描述】:

我正在尝试测试 Laravel api。 当我尝试使用 Eloquent 模型填充方法创建部分模拟时,phpunit 会抛出错误。

代码

$mock = m::mock('App\User', [])->makePartial();
$mock->shouldReceive('fill')->once()->andReturn('ok');
$result = $mock->fill([]);
var_dump($result);

错误

PHP Fatal error:  Call to a member function __call() on a non-object
PHP Fatal error:  Uncaught exception 'Illuminate\Contracts\Container\BindingResolutionException' with message 'Target [Illuminate\Contracts\Debug\ExceptionHandler] is not instantiable.

我真的不知道这是 Eloquent 错误,还是 Mockery 错误。

注意事项:

我暂时使用Model::update方法解决了这个问题,而不是Model::fill然后Model::save,但我还是想知道如何模拟fill方法。

链接

http://laravel.com/api/5.0/Illuminate/Database/Eloquent/Model.html#method_fill

【问题讨论】:

【参考方案1】:

我认为创建了模拟对象但没有此方法。您需要为 fill() 方法定义一个期望来指示她的模拟行为。喜欢:

$mock->shouldReceive('fill')->once()->andReturn('ok');

希望对你有帮助。

【讨论】:

没错,使用 [methodName] 意味着只应模拟该方法。 这个答案几乎完全正确。如果我添加该行,它仍然会引发相同的错误,但您帮助找到了真正的问题。真正的问题如下,模型构造函数调用了填充函数,这发生在添加期望之前。所以,我正在寻找如何解决这个问题,我发现我需要创建一个部分模拟,但现在它引发了另一个错误。【参考方案2】:

您也可以使用被动部分模拟:

$mock = m::mock('Model')->makePartial();
$mock->shouldReceive("fill")->once()->andReturn("ok");

在被动部分中,所有方法都将简单地遵循父类的原始方法,除非方法调用符合已知的期望。并且会跳过Model构造函数中意外的fill方法的调用。

【讨论】:

谢谢,我做到了,但现在又抛出一个错误,我还在寻找如何模拟填充方法。 它抛出以下错误: PHP 致命错误:在非对象 PHP 上调用成员函数 __call() 致命错误:未捕获异常 'Illuminate\Contracts\Container\BindingResolutionException' 并带有消息[Illuminate\Contracts\Debug\ExceptionHandler] 不可实例化。

以上是关于Mockery 无法使用 Eloquent 模型填充方法创建部分模拟的主要内容,如果未能解决你的问题,请参考以下文章

使用 Mockery Eloquent 模型模拟 Laravel

在 Laravel(流明)上使用 Mockery 模拟 Eloquent 模型不起作用

为啥 Mockery 无法为我的模型创建别名

模拟静态 Eloquent 模型方法,包括 find()

使用 find() 模拟 Eloquent 模型

在 Mockery 中测试链式方法调用