首页 > 解决方案 > 如何使用 Phpunit 测试 laravel Mailer

问题描述

我需要使用 PHPunit 测试 Laravel Mailer,我正在使用CRUD操作,如果任何一种方法失败,它应该触发邮件。我需要测试邮件部分,下面是代码。

 public function index()
    {
       
        $response = Http::withBasicAuth(userName,passWord)
            ->get(connection());
        $this->html_mail($response);
        return $response->json();
    }
 public function show($id)
    {
      $response = Http::withBasicAuth(userName, passWord)
            ->get(connection());
        // check response & send mail if error
        $this->html_mail($response);
        $record = collect($response->json() ['output'])
            ->where($this->primaryKeyname, $id)->first();
        return $record;
    }

邮寄方式:

 public function html_mail($response)
    {
        if ($response->failed() || $response->serverError() || $response->clientError()) {
            Mail::send([], [], function ($message) use ($response) {
                $message->to('foo@example.com');
                $message->subject('Sample test');
                $message->setBody($response, 'text/html');
            });
        }

        return 'Mail Sent Successfully';
    }
}

有人可以帮助测试使用 PHPunit 的 Mailer 方法。谢谢。

标签: phpphpunitlaravel-7

解决方案


看起来您的示例中可能缺少一些代码,但通常您正在寻找Laravel 的Mail::fake()方法

# tests/Feature/YourControllerTest.php

use Illuminate\Support\Facades\Mail;

/**
 * @test
 */
public function index_should_send_an_email_if_authentication_fails(): void
{
    Mail::fake();

    $this->withToken('invalidToken', 'Basic')
        ->get('your.route.name');

    Mail::assertSent(function ($mail) {
        // Make any assertions you need to in here.
        return $mail->hasTo('foo@example.com');
    });
}

通过利用中间件进行身份验证而不是在每个方法中重复它,还有一个机会在这里清理您的控制器方法。

深入研究,如果身份验证失败Illuminate\Auth\SessionGuard,Laravel 会自动触发一个Illuminate\Auth\Events\Failed事件。您可以考虑注册一个事件侦听器并将其附加到该事件,而不是直接从您的控制器发送,然后让该侦听器发送一个可邮寄的通知

# app/Providers/EventServiceProvider

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'Illuminate\Auth\Events\Failed' => [
        'App\\Listeners\\FailedAuthAttempt',
    ],
];

通过这些更改,您的测试也变得更加容易:

# tests/Feature/Notifications/FailedAuthAttemptTest.php

use App\Notifications\FailedAuthAttempt;
use Illuminate\Notifications\AnonymousNotifiable;
use Illuminate\Support\Facades\Notification;

/**
 * @test
 */
public function it_should_send_an_email_upon_authentication_failure(): void
{
    Notification::fake();

    $this->withToken('invalidToken', 'Basic')
        ->get('your.route.name');

    Notification::assertSentTo(new AnonymousNotifiable(), FailedAuthAttempt::class);
}

现在,应用程序中使用 Laravelauth.basic中间件的任何路由都会在失败时自动发送FailedAuthAttempt通知。例如,这也使得将这些通知发送到 Slack 频道而不是发送电子邮件变得更容易。


推荐阅读