闭包内的嘲笑模拟方法
Mockery mock method inside closure
我在 call_user_func()
示例调用的闭包内部单元测试方法有问题:
public function trans($lang, $callback)
{
$this->sitepress->switch_lang($lang);
call_user_func($callback);
}
在控制器上:
public function sendMail()
{
$foo = $baz = 'something';
$mail = $this->mailer;
$this->helper->trans_c('en', function() use($foo, $baz, $mail) {
$mail->send('Subject', $foo, $baz);
});
}
测试用例:
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();
}
如何确保 ->send()
方法在闭包中被调用 trans_c()
我试过
$helperMock->shouldReceive('trans_c')->with('en', function() use($mailMock) {
$mailMock->shouldReceive('send');
});
运气不好。 :(
在 trans_c
的第二个参数中传递 Mockery::type('Closure')
效果很好,但我真的需要确保调用邮件程序 class 的方法 send
。
模拟的 class 默认情况下不执行真实代码。如果你模拟助手,它会检查调用是否正在进行,但不会执行匿名函数。
使用 mockery,你可以配置期望,以便执行真正的方法:passthru();
试试这个:
$helperMock = Mockery::mock('Acme\Helper');
$helperMock
->shouldReceive('trans_c')
->once()
->passthru()
;
这在 the docs 中有解释。
编辑
也许您真的不需要模拟助手。如果你 mock Mail class 并希望 send 方法被调用一次,就让真正的助手来做吧。
我在 call_user_func()
示例调用的闭包内部单元测试方法有问题:
public function trans($lang, $callback)
{
$this->sitepress->switch_lang($lang);
call_user_func($callback);
}
在控制器上:
public function sendMail()
{
$foo = $baz = 'something';
$mail = $this->mailer;
$this->helper->trans_c('en', function() use($foo, $baz, $mail) {
$mail->send('Subject', $foo, $baz);
});
}
测试用例:
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();
}
如何确保 ->send()
方法在闭包中被调用 trans_c()
我试过
$helperMock->shouldReceive('trans_c')->with('en', function() use($mailMock) {
$mailMock->shouldReceive('send');
});
运气不好。 :(
在 trans_c
的第二个参数中传递 Mockery::type('Closure')
效果很好,但我真的需要确保调用邮件程序 class 的方法 send
。
模拟的 class 默认情况下不执行真实代码。如果你模拟助手,它会检查调用是否正在进行,但不会执行匿名函数。
使用 mockery,你可以配置期望,以便执行真正的方法:passthru();
试试这个:
$helperMock = Mockery::mock('Acme\Helper');
$helperMock
->shouldReceive('trans_c')
->once()
->passthru()
;
这在 the docs 中有解释。
编辑
也许您真的不需要模拟助手。如果你 mock Mail class 并希望 send 方法被调用一次,就让真正的助手来做吧。