如何测试Laravel 4中的Mail Facade

时间:2013-08-23 15:25:00

标签: laravel laravel-4

我似乎无法让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!');
});

1 个答案:

答案 0 :(得分:24)

下面的代码示例假定PHP 5.4或更高版本 - 如果您使用的是5.3,则需要在以下代码之前添加$self = $this并在第一个闭包上添加use ($self),并替换所有引用封闭内部$this

模拟SwiftMailer

最简单的方法是模拟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它接受任何内容。