LoginSignup
1
0

More than 3 years have passed since last update.

【Laravel】テスト内にメールとSMSのテストを両立させたい

Last updated at Posted at 2019-10-11

問題定義

「メール通知のテストをしたい」「SMS通知(自作Notifier)のテストをしたい」といったとき、
モックを使用すると安全に実行ができ、実行結果の取得も容易にすることができます。

\Illuminate\Support\Facades\Mail::fake();
\Illuminate\Support\Facades\Notification::fake();

ところが、下記のように両方を使用してしまうと、
想定したようにはテストが動きません。

Customer.php
class Customer {
    use \Illuminate\Notifications\Notifiable

    public function notify()
    {
        $this->notify(new MyNotifyInstance($this->notifier));
    }
}
CustomerTest.php
class CustomerTest extends TestCase
{
    protected function setUp()
    {
        parent::setUp();
        Mail::fake();
        Notification::fake();
    }

    public function testMailNotification()
    {
        $customer = factory(Customer::class)->create([
            'notifier' => 'mail'
        ]);

        $customer->notify();

        Mail::assertSent(MyCustomerMail::class, 1);  //-> エラー。0件となる
    }

    public function testSMSNotification()
    {
        $customer = factory(Customer::class)->create([
            'notifier' => 'sms'
        ]);

        $customer->notify();

        Notification::assertSentTo(  //->OK
            [$customerForSMS ], MySMSNotification::class
        );
    }
}

解決策

CustomerTest.php
class CustomerTest extends TestCase
{
    protected function setUp()
    {
        parent::setUp();
    }

    public function testMailNotification()
    {
        Mail::fake();  //個別に設定するよう変更

        $customer = factory(Customer::class)->create([
            'notifier' => 'mail'
        ]);
        $customer->notify();
        Mail::assertSent(MyCustomerMail::class, 1);
    }

    public function testSMSNotification()
    {
        Notification::fake();  //個別に設定するよう変更

        $customer = factory(Customer::class)->create([
            'notifier' => 'sms'
        ]);
        $customer->notify();
        Notification::assertSentTo(
            [$customer], MySMSNotification::class
        );
    }
}

原因

Notification::fake() が Mail::fake() を上から潰しているようです。

メール送信処理が発火されず、実行件数が0件となるため、
Mail::fake()を使用する際にはNotification::fake()が実行されないようにします。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0