我似乎无法让Mail Facade接受->with()
测试命令。
这有效:
Mail::shouldReceive('send')->once();
但这不起作用:
Mail::shouldReceive('send')->with('emails.welcome')->once();
,这也不是:
Mail::shouldReceive('send')->with('emails.welcome', array(), function(){})->once();
,这也不是:
Mail::shouldReceive('send')->with('emails.welcome', array(), function($message){})->once();
全部给出以下错误:
"No matching handler found for Illuminate\Mail\Mailer::send("emails.welcome", Array, Closure)"
那么如何测试Mail以检查它接收的是什么?
另外 - 对于奖励积分 - 是否可以测试Mail在闭包内做什么?即,我可以查看$message->to()
设置的内容吗?
编辑:我的邮件代码:
Mail::send("emails.welcome", $data, function($message)
{
$message->to($data['email'], $data['name'])->subject('Welcome!');
});
答案 0 :(得分:24)
下面的代码示例假定PHP 5.4或更高版本 - 如果您使用的是5.3,则需要在以下代码之前添加$self = $this
并在第一个闭包上添加use ($self)
,并替换所有引用封闭内部$this
。
最简单的方法是模拟Swift_Mailer实例。您必须了解Swift_Message类中存在哪些方法才能充分利用它。
$mock = Mockery::mock('Swift_Mailer');
$this->app['mailer']->setSwiftMailer($mock);
$mock->shouldReceive('send')->once()
->andReturnUsing(function(\Swift_Message $msg) {
$this->assertEquals('My subject', $msg->getSubject());
$this->assertEquals('foo@bar.com', $msg->getTo());
$this->assertContains('Some string', $msg->getBody());
});
解决此问题的另一种方法是对传递给Mail::send
的闭包运行断言。这看起来并不那么简洁,它的错误信息可能相当神秘,但它有效,非常灵活,并且该技术也可以用于其他事情。
use Mockery as m;
Mail::shouldReceive('send')->once()
->with('view.name', m::on(function($data) {
$this->assertContains('my variable', $data);
return true;
}), m::on(function($closure) {
$message = m::mock('Illuminate\Mailer\Message');
$message->shouldReceive('to')
->with('test@example.com')
->andReturn(m::self());
$message->shouldReceive('subject')
->with('Email subject')
->andReturn(m::self());
$closure($message);
return true;
}));
在这个例子中,我正在对传递给视图的数据运行断言,如果收件人地址,主题或视图名称错误,我将从Mockery收到错误。
Mockery::on()
允许您对模拟方法的参数运行闭包。如果它返回false,你将得到“找不到匹配的处理程序”,但我们想要运行断言,所以我们只返回true。 Mockery::self()
允许链接方法。
如果您在任何时候不关心方法调用的某个参数是什么,您可以使用Mockery::any()
告诉Mockery它接受任何内容。