8

我似乎无法让邮件外观接受->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!');
});
4

1 回答 1

25

下面的代码示例假定 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 它接受任何东西。

于 2013-08-25T16:36:01.250 回答