如何测试监听器发送的 Laravel 通知?

Zai*_*ris 5 unit-testing laravel

我有一个工作代码,当创建客户记录时,将调度一个事件,然后侦听器将向客户的代理发送通知。

事件服务提供者.php

protected $listen = [
        'App\Events\CustomerCreated' => [
            'App\Listeners\TriggerExternalCustomerCreation',
            'App\Listeners\SendNotificationCustomerCreated',
        ],
]
Run Code Online (Sandbox Code Playgroud)

SendNotificationCustomerCreated.php

public function handle(CustomerCreated $event)
    {
        $when = now()->addMinutes(0);
        $event->customer->manager->notify((new CustomerCreatedNotification($event->customer))->delay($when));
    }
Run Code Online (Sandbox Code Playgroud)

这是我的测试用例:-

public function customer_created_event_dispatch()
    {
        // $this->markTestIncomplete('This test has not been implemented yet.');
        $this->withoutExceptionHandling();
        Event::fake();
        Notification::fake();

        $user = factory(User::class)->states('order management')->create();
        $data = $this->data(['address' => true, 'contact' => true]);

        $response = $this->actingAs($user)->post(route('customers.store'), $data);
        $response->assertSessionHasNoErrors();

        $customers = Customer::all();
        $customer = $customers->first();
        $manager = $customer->manager;

        $this->assertCount(1, $customers);

        Event::assertDispatched(CustomerCreated::class, function ($event) use ($customers) {
            return $event->customer->id === $customers->first()->id;
        });

        Notification::assertSentTo(
            $manager,
            CustomerCreatedNotification::class,
            function ($notification, $channels) use ($customer) {
                return $notification->customer->id === $customer->id;
            }
        );
    }
Run Code Online (Sandbox Code Playgroud)

最初侦听器已排队,但我尝试从队列中删除,但错误仍然存​​在。

我可以确认该事件确实调度,因为它通过了 Event::assertDispatched。但在最后一个断言中失败并出现以下错误:-

The expected [App\Notifications\CustomerCreatedNotification] notification was not sent
Run Code Online (Sandbox Code Playgroud)

mrh*_*rhn 6

伪造事件会覆盖普通的事件逻辑,因此不会触发侦听器。这很有用,因为您有时需要阻止事件链触发。伪造也是关于不关心副作用,因为它们通常很难测试。

但是你如何测试你的代码是否工作,我更喜欢将事件副作用测试分离到单元测试中。与作业相同的方法,因为如果您需要测试端点和作业链,则副作用更难断言并且测试会变得非常庞大。

从原始测试中删除断言通知。在tests/Unit/TestCustomerCreatedEvent任何有意义的路径中创建一个新路径。

public function customer_event_listener_tests() {
    // create your data
    $customers = Customer::all();
    $customer = $customers->first();
    $manager = $customer->manager;

    // fake notification only
    Notification::fake();

    $event = new CustomerCreated($customer);
    event($event);

    Notification::assertSentTo(
        $manager,
        CustomerCreatedNotification::class,
        function ($notification, $channels) use ($customer) {
            return $notification->customer->id === $customer->id;
        }
    );
}
Run Code Online (Sandbox Code Playgroud)