簡體   English   中英

我的 Laravel 通知測試不起作用

[英]My Laravel notification test does not work

在我的應用程序中,我正在測試我的OrderController ,我必須檢查是否已發送通知。

我在 controller 中使用一項服務,該服務使用OrderDeletedNotification觸發order->notify方法。 在我的測試中,我使用Mail::fake()Notification::fake() ,我嘗試斷言正確的事情,但它還沒有發生。 代碼有什么問題?

我的訂單model是這樣的:

class Order extends Model
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        // ...
        'member_id',
        // ...
    ];


    public function member(): BelongsTo
    {
        return $this->belongsTo(Member::class, 'member_id');
    }

    /**
     * Route notifications for the mail channel.
     *
     * @param  \Illuminate\Notifications\Notification  $notification
     * @return array|string
     */
    public function routeNotificationForMail($notification)
    {
        return $this->member->email;
    }

在我的controller里面有更新方法:

    /**
     * Update the specified resource in storage.
     *
     * @param  \Domain\Webshop\Http\Requests\Order\UpdateOrderRequest  $request
     * @param  string  $id
     * @return \Illuminate\Http\Response
     */
    public function update(UpdateOrderRequest $request, string $id)
    {
        $order_id = $this->repository->update($request, $id);

        $order = Order::whereId($order_id)->first();

        $this->service->sendOrderUpdatedNotification($order);

        return response()->json([
            'id' => $order_id
        ]);
    }

這是訂單服務:

public function sendOrderUpdatedNotification(Order $order): void
{
    if (is_null($order)) {
        return;
    };

    $this->order = $order;

    $toMember = $this->getToMemberEmail();

    $subject = OrderMailDefault::UPDATED_SUBJECT;

    // send the notification
    $this->order->notify(new OrderUpdatedNotification($toMember, $subject, $order));
}

這是我的訂單更新通知:

class OrderUpdatedNotification extends Notification implements ShouldQueue
{
    use Queueable;

    public string $subject;

    public string $email;

    public Order $order;

    public function __construct(string $to = null, string $subject = '', Order $order = null)
    {
        if (is_null($to)) {
            return;
        }

        if (is_null($order)) {
            return;
        }

        $this->subject = $subject ?? '';

        $this->email = $to;

        $this->order = $order;
    }

    public function via(mixed $notifiable): array
    {
        return ['mail'];
    }

    public function viaQueues(): array
    {
        return [
            'mail' => QueueEnum::EMAIL,
        ];
    }

    public function toMail(mixed $notifiable): OrderUpdatedMail
    {
        return (new OrderUpdatedMail($this->order))
            ->to($this->email)
            ->subject($this->subject);
    }
}

這是我的測試:

class OrderControllerRegisteredUserTest extends BaseTestCase
{
    protected function setUp(): void
    {
        parent::setUp();

        $this->model = Order::class;

        $this->controller = OrderController::class;

        Mail::fake();
    }

    public function create(int $count): void
    {
        $this->model::factory()
            // ...
            ->forMember()
            // ...
            ->create();
    }

    /** @test */
    public function shouldUpdateAsAuthorizedUser(): void
    {
        $this->create(1);

        $item = $this->model::first();

        $item->name = $item->name . ' Changed';

        $data = $item->toArray();

        $this->put(action([$this->controller, 'update'], $item->id), $data)
            ->assertOk();

        Notification::fake();

        // Assert the notification was sent...
        Notification::assertSentTo(
            [$item->member],
            OrderUpdatedNotification::class,
        );
    }

結果是這樣的:

ParaTest v6.6.5 upon PHPUnit 9.5.26 by Sebastian Bergmann and contributors.

F                                                                   1 / 1 (100%)

Time: 00:01.354, Memory: 10.00 MB

There was 1 failure:

1) Domain\Webshop\Tests\Order\OrderControllerRegisteredUserTest::shouldUpdateAsAuthorizedUser
The expected [Domain\Webshop\Notifications\OrderUpdatedNotification] notification was not sent.
Failed asserting that false is true.

/var/www/html/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/NotificationFake.php:83
/var/www/html/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/NotificationFake.php:67
/var/www/html/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:338
/var/www/html/src/Domain/Webshop/Tests/Order/OrderControllerRegisteredUserTest.php:100

我認為您應該在發送請求之前放置Notification::fake()以便正確偽造通知


所以你的測試應該是這樣的:

/** @test */
public function shouldUpdateAsAuthorizedUser(): void
{
    $this->create(1);

    $item = $this->model::first();

    $item->name = $item->name . ' Changed';

    $data = $item->toArray();

    Notification::fake();

    $this->put(action([$this->controller, 'update'], $item->id), $data)
        ->assertOk();

    // Assert the notification was sent...
    Notification::assertSentTo(
        [$item->member],
        OrderUpdatedNotification::class,
    );
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM