如何测试Laravel 4中的Mail Facade

Lau*_*nce 8 laravel laravel-4

我似乎无法让Mail Facade接受->with()测试命令.

这有效:

Mail::shouldReceive('send')->once();
Run Code Online (Sandbox Code Playgroud)

但这不起作用:

Mail::shouldReceive('send')->with('emails.welcome')->once();
Run Code Online (Sandbox Code Playgroud)

这两个都没有:

Mail::shouldReceive('send')->with('emails.welcome', array(), function(){})->once();
Run Code Online (Sandbox Code Playgroud)

这两个都没有:

Mail::shouldReceive('send')->with('emails.welcome', array(), function($message){})->once();
Run Code Online (Sandbox Code Playgroud)

全部给出以下错误:

"No matching handler found for Illuminate\Mail\Mailer::send("emails.welcome", Array, Closure)"
Run Code Online (Sandbox Code Playgroud)

那么我如何测试Mail以检查它接收的是什么?

另外 - 对于奖励积分 - 是否可以测试封闭内部正在做什么?即我可以检查$message->to()设置的内容吗?

编辑:我的邮件代码:

Mail::send("emails.welcome", $data, function($message)
{
    $message->to($data['email'], $data['name'])->subject('Welcome!');
});
Run Code Online (Sandbox Code Playgroud)

And*_*eas 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());
    });
Run Code Online (Sandbox Code Playgroud)

关闭闭包的断言

另一种解决方法是在传递给的闭包上运行断言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;
    }));
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我正在对传递给视图的数据运行断言,如果收件人地址,主题或视图名称错误,我将从Mockery收到错误.

Mockery::on()允许您对模拟方法的参数运行闭包.如果它返回false,你将得到"找不到匹配的处理程序",但我们想要运行断言,所以我们只返回true.Mockery::self()允许链接方法.

如果在任何时候你不关心方法调用的某个参数是什么,你可以Mockery::any()用来告诉Mockery它接受任何东西.