php Laravel 5.4测试Mail::fake -如何访问邮件正文?

ycl3bljg  于 2022-12-28  发布在  PHP
关注(0)|答案(6)|浏览(134)

我正在运行Laravel 5.4并使用Mail::fake()和Mail::assertSent()测试Mailables。有一些Assert用于hasTo($email)和hasCc($email),但似乎没有访问邮件内容的方法。我想测试电子邮件正文是否包含特定字符串。
伪代码:

Mail::assertSent(UserInvited::class, function($mail) use($token) {
    return $mail->bodyContains($token); # that method does not really exist
});

这可能吗?

t9aqgxwy

t9aqgxwy1#

遇到同样的情况,但搜索没有任何运气-调试后:

Mail::assertSent(InstanceOfMailableEmail::class, function($mail) use ($needle) {

    // now your email has properties set
    $mail->build(); 

    //check the content body for a string
    return strpos($mail->viewData['content'], $needle) !== false;
});
x759pob2

x759pob22#

有一个软件包可以用来测试邮件。但是到目前为止,你必须有点创造性才能让它工作,因为他们还没有在reqs中指定Laravel 5.4.。所以,进入你的composer.json文件,从这个repo构建你自己的软件包,其中包含更新后的Laravel 5.4. 要求,如下所示:

"repositories": [
    {
        "type": "package",
        "package": {
            "name": "spinen/laravel-mail-assertions",
            "version": "0.1.2",
            "require": {
                "php": ">=5.5.0",
                "illuminate/support": "~5.1.10|5.2.*|5.3.*|5.4.*",
                "swiftmailer/swiftmailer": "~5.1"
            },
            "require-dev": {
                "mockery/mockery": "^0.9.1",
                "phpunit/phpunit": "~4.0|~5.0",
                "psy/psysh": "^0.5.1",
                "satooshi/php-coveralls": "^0.6.1",
                "symfony/var-dumper": "~2.7|~3.0"
            },
            "autoload": {
                "psr-4": {
                    "Spinen\\MailAssertions\\": "src"
                }
            },
            "autoload-dev": {
                "psr-4": {
                    "Spinen\\MailAssertions\\": "tests"
                }
            },
            "config": {
                "preferred-install": "dist"
            },
            "dist": {
                "url": "https://github.com/spinen/laravel-mail-assertions/archive/0.1.1.zip",
                "type": "zip"
            }
        }
    }
],

然后,在require-dev下添加您的自定义包:

"require-dev": {
    "spinen/laravel-mail-assertions": "^0.1.2"
},

一旦你安装好了MAIL_DRIVER=log,在你的.env文件中设置MAIL_DRIVER=log,然后把Spinen\MailAssertions\MailTracking trait拉到你的测试中,这个trait有seeEmailContainsseeEmailSubjectContains等方法来Assert文本存在于任何发送的电子邮件中。

vxf3dgd4

vxf3dgd43#

下面是我的做法(沿着一些关于如何做其他事情的有用提示):

Mail::fake(); //https://laravel.com/docs/5.7/mocking#mail-fake
$firstName = 'Sally';    
$self = $this;
Mail::assertQueued(MyMailable::class, function($mail) use($self, $firstName) {
    $mail->build(); // to set the email properties            
    $self->assertEquals($firstName, $mail->viewData["firstName"]);
    $self->assertEquals(["X-SES-CONFIGURATION-SET" => config('services.ses.options.ConfigurationSetName')], $mail->getHeaders());
    $self->assertTrue($mail->hasBcc(config('mail.supportTeam.address'), config('mail.supportTeam.name')));
    return true;
});
2mbi3lxu

2mbi3lxu4#

GitHub上有一个问题要求这样做:https://github.com/laravel/ideas/issues/405
泰勒似乎没有发表评论就结束了这一请求。
如果你想检查一个字符串是否在呈现的邮件中,你可以不模仿邮件外观,只需要这样做:

$mail  = new Mailable(...);
$html  = $mail->render();
$found = (strpos($html, 'Hello') !== false);
ogq8wdun

ogq8wdun5#

在创建一个伪邮件管理器之前保留原始邮件管理器的技巧可以达到这个目的。一旦你准备好运行Mailable的Assert,恢复原始的MM。
示例:

public function testInvite(): void
    {
        $mailerOriginal = Mail::getFacadeRoot();
        static::assertTrue(\assert($mailerOriginal instanceof MailManager));
        Mail::fake();

        // --- Your test logic. --- 

        // Note that the callback will be called as many times as there
        // were emails sent (of the given type).
        Mail::assertSent(DocumentShareAccess::class, function (DocumentShareAccess $mail) use ($mailerOriginal): bool {
            // The fake has no rendering capability, so have to swap back.
            Mail::swap($mailerOriginal);

            $mail->assertSeeInHtml('contact the document owner');
            static::assertTrue($mail->hasTo($invitee->email), $invitee->email);

            return true;
        });
    }
czfnxgou

czfnxgou6#

这样我们甚至可以在5.4中渲染身体:

Mail::assertSent($mailable, function ($mail) use ($needle) {
    $m = $mail->build();
    $body = view($m->view, $m->viewData)->render();

    return strpos($body, $needle) !== false;
});

https://github.com/laravel/ideas/issues/405#issuecomment-412427637开始

相关问题