闭包内的嘲讽模拟方法

rob*_*obs 3 phpunit unit-testing mocking mockery laravel-4

我在call_user_func()示例调用的闭包内有问题的单元测试方法:

public function trans($lang, $callback)
{
   $this->sitepress->switch_lang($lang);
   call_user_func($callback);
}
Run Code Online (Sandbox Code Playgroud)

在控制器上:

public function sendMail()
{
   $foo = $baz = 'something';
   $mail = $this->mailer;
   $this->helper->trans_c('en', function() use($foo, $baz, $mail) {
      $mail->send('Subject', $foo, $baz);
   });
}
Run Code Online (Sandbox Code Playgroud)

测试用例 :

public function testSomething()
{
   $helperMock = Mockery::mock('Acme\Helper');
   $helperMock->shouldReceive('trans_c')->once(); // passed

   $mailMock = Mockery::mock('Acme\Mail');
   $mailMock->shouldReceive('send')->once(); // got should be called 1 times instead 0

   $act = new SendMailController($helperMock, $mailMock);
   $act->sendMail();
}
Run Code Online (Sandbox Code Playgroud)

如何确保->send()在闭包内调用该方法trans_c()

我试过

$helperMock->shouldReceive('trans_c')->with('en', function() use($mailMock) {
   $mailMock->shouldReceive('send');
});
Run Code Online (Sandbox Code Playgroud)

没运气。:(

好吧,通过传入Mockery::type('Closure')的第二个参数可以正常工作trans_c,但我确实需要确保send调用邮件程序类中的方法。

gon*_*lez 5

默认情况下,模拟类不执行真正的代码。如果您模拟助手,它将检查是否正在进行调用,但不会执行匿名函数。

使用 mockery,您可以配置期望,以便执行真正的方法: passthru();

尝试这个:

$helperMock = Mockery::mock('Acme\Helper');
$helperMock
     ->shouldReceive('trans_c')
     ->once()
     ->passthru()
;
Run Code Online (Sandbox Code Playgroud)

这在文档中进行解释。

编辑

也许你真的不需要嘲笑助手。如果您模拟 Mail 类并期望调用一次 send 方法,就让真正的助手来做。