我似乎无法让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)"


因此,如何测试邮件以检查其接收的内容?

另外-为了获得奖励积分-是否可以测试封包内部的邮件功能?即可以检查$message->to()设置为什么吗?

编辑:我的邮件代码:

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

最佳答案

下面的代码示例假定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('[email protected]', $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('[email protected]')
            ->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它接受任何东西。

08-18 09:37