Mockery:模拟对象

时间:2016-03-24 18:18:32

标签: laravel laravel-5.2 mockery laravel-testing

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

但是我现在发现,当一个雄辩的模型被保存时,它会抛出一个触发听众的事件。这个监听器负责启动对mock对象的调用。

我发现当我做类似以下的事情时,它会起作用。

$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 Models实际上使用了神奇的___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 个答案:

答案 0 :(得分:0)

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