نسخه:

مناسبت ها

معرفی

رویدادهای لاراول یک پیاده‌سازی الگوی مشاهده‌گر ساده را ارائه می‌دهند، که به شما امکان می‌دهد مشترک شوید و به رویدادهای مختلفی که در برنامه شما رخ می‌دهد گوش دهید. کلاس‌های رویداد معمولاً در app/Events دایرکتوری ذخیره می‌شوند، در حالی که شنوندگان آن‌ها در دایرکتوری ذخیره می‌شوند app/Listeners . اگر این دایرکتوری ها را در برنامه خود نمی بینید، نگران نباشید، زیرا هنگام ایجاد رویدادها و شنوندگان با استفاده از دستورات کنسول Artisan، برای شما ایجاد می شوند.

رویدادها راهی عالی برای جدا کردن جنبه‌های مختلف برنامه شما هستند، زیرا یک رویداد می‌تواند چندین شنونده داشته باشد که به یکدیگر وابسته نیستند. به عنوان مثال، ممکن است بخواهید هر بار که سفارش ارسال می شود، یک اعلان Slack برای کاربر خود ارسال کنید. به جای اینکه کد پردازش سفارش خود را به کد اعلان Slack متصل کنید، می توانید App\Events\OrderShipped رویدادی را مطرح کنید که شنونده می تواند آن را دریافت کرده و از آن برای ارسال اعلان Slack استفاده کند.

ایجاد رویدادها و شنوندگان

برای تولید سریع رویدادها و شنوندگان، می توانید از دستورات make:event و make:listener Artisan استفاده کنید:

php artisan make:event PodcastProcessed
 
php artisan make:listener SendPodcastNotification --event=PodcastProcessed

برای راحتی، می‌توانید دستورات make:event و make:listener Artisan را بدون آرگومان‌های اضافی فراخوانی کنید. هنگامی که این کار را انجام می دهید، لاراول به طور خودکار نام کلاس و هنگام ایجاد شنونده، رویدادی را که باید به آن گوش دهد از شما می خواهد:

php artisan make:event
 
php artisan make:listener

ثبت رویدادها و شنوندگان

کشف رویداد

به طور پیش فرض، لاراول به طور خودکار شنوندگان رویداد شما را با اسکن دایرکتوری برنامه شما پیدا و ثبت می کند Listeners . وقتی لاراول هر متد کلاس شنونده ای را پیدا می کند که با handle یا شروع می شود __invoke ، لاراول آن متدها را به عنوان شنونده رویداد برای رویدادی که به صورت تایپ در امضای متد ذکر شده است، ثبت می کند:

use App\Events\PodcastProcessed;
 
class SendPodcastNotification
{
/**
* Handle the given event.
*/
public function handle(PodcastProcessed $event): void
{
// ...
}
}

اگر قصد دارید شنوندگان خود را در یک دایرکتوری دیگر یا در چندین دایرکتوری ذخیره کنید، می توانید به لاراول دستور دهید تا آن دایرکتوری ها را با استفاده از روش موجود withEvents در فایل برنامه شما اسکن کند bootstrap/app.php :

->withEvents(discover: [
__DIR__.'/../app/Domain/Listeners',
])

این event:list دستور ممکن است برای لیست کردن تمام شنوندگان ثبت شده در برنامه شما استفاده شود:

php artisan event:list

کشف رویداد در تولید

برای افزایش سرعت برنامه خود، باید مانیفست تمام شنوندگان برنامه خود را با استفاده از دستورات optimize یا event:cache Artisan در حافظه پنهان ذخیره کنید. به طور معمول، این دستور باید به عنوان بخشی از فرآیند استقرار برنامه شما اجرا شود . این مانیفست توسط چارچوب برای سرعت بخشیدن به روند ثبت رویداد استفاده می شود. این event:clear دستور ممکن است برای از بین بردن حافظه پنهان رویداد استفاده شود.

ثبت دستی رویدادها

با استفاده از Event نما، می‌توانید رویدادها و شنوندگان مربوط به آن‌ها را به‌صورت دستی در boot روش برنامه‌تان ثبت کنید AppServiceProvider :

use App\Domain\Orders\Events\PodcastProcessed;
use App\Domain\Orders\Listeners\SendPodcastNotification;
use Illuminate\Support\Facades\Event;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Event::listen(
PodcastProcessed::class,
SendPodcastNotification::class,
);
}

این event:list دستور ممکن است برای لیست کردن تمام شنوندگان ثبت شده در برنامه شما استفاده شود:

php artisan event:list

شنوندگان بسته

به طور معمول، شنوندگان به عنوان کلاس ها تعریف می شوند. با این حال، شما همچنین می توانید شنوندگان رویداد مبتنی بر بسته شدن را به صورت دستی در boot روش برنامه خود ثبت کنید AppServiceProvider :

use App\Events\PodcastProcessed;
use Illuminate\Support\Facades\Event;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Event::listen(function (PodcastProcessed $event) {
// ...
});
}

شنوندگان رویداد ناشناس در صف

هنگام ثبت شنوندگان رویداد مبتنی بر بسته شدن، می توانید بسته شدن شنونده را در Illuminate\Events\queueable تابع بپیچید تا به لاراول دستور دهید شنونده را با استفاده از صف اجرا کند :

use App\Events\PodcastProcessed;
use function Illuminate\Events\queueable;
use Illuminate\Support\Facades\Event;
 
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Event::listen(queueable(function (PodcastProcessed $event) {
// ...
}));
}

مانند کارهای در صف، می توانید از متدهای onConnection ، onQueue و delay برای سفارشی کردن اجرای شنونده در صف استفاده کنید:

Event::listen(queueable(function (PodcastProcessed $event) {
// ...
})->onConnection('redis')->onQueue('podcasts')->delay(now()->addSeconds(10)));

catch اگر می‌خواهید شکست‌های شنونده در صف ناشناس را مدیریت کنید، ممکن است در حین تعریف شنونده، روش را ببندید queueable . این بسته، نمونه رویداد و Throwable نمونه ای را که باعث شکست شنونده شده است، دریافت می کند:

use App\Events\PodcastProcessed;
use function Illuminate\Events\queueable;
use Illuminate\Support\Facades\Event;
use Throwable;
 
Event::listen(queueable(function (PodcastProcessed $event) {
// ...
})->catch(function (PodcastProcessed $event, Throwable $e) {
// The queued listener failed...
}));

شنوندگان رویداد Wildcard

همچنین می‌توانید شنوندگان را با استفاده از * کاراکتر به‌عنوان پارامتر عام ثبت کنید، که به شما امکان می‌دهد چندین رویداد را در یک شنونده مشاهده کنید. شنوندگان Wildcard نام رویداد را به عنوان اولین آرگومان و کل آرایه داده رویداد را به عنوان آرگومان دوم دریافت می کنند:

Event::listen('event.*', function (string $eventName, array $data) {
// ...
});

تعریف رویدادها

یک کلاس رویداد اساساً یک محفظه داده است که اطلاعات مربوط به رویداد را در خود نگه می دارد. به عنوان مثال، فرض کنید یک App\Events\OrderShipped رویداد یک شی ORM Eloquent دریافت می کند:

<?php
 
namespace App\Events;
 
use App\Models\Order;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
 
class OrderShipped
{
use Dispatchable, InteractsWithSockets, SerializesModels;
 
/**
* Create a new event instance.
*/
public function __construct(
public Order $order,
) {}
}

همانطور که می بینید، این کلاس رویداد هیچ منطقی ندارد. این یک ظرف برای App\Models\Order نمونه ای است که خریداری شده است. در صورتی که شی SerializesModels رویداد با استفاده از serialize تابع PHP، مانند زمانی که از شنوندگان در صف استفاده می‌شود، سریال‌سازی شود، ویژگی مورد استفاده رویداد، هر مدل Eloquent را به‌خوبی سریال‌سازی می‌کند .

تعریف شنوندگان

در مرحله بعد، بیایید نگاهی به شنونده رویداد نمونه خود بیاندازیم. شنوندگان رویداد نمونه های رویداد را در handle روش خود دریافت می کنند. دستور make:listener Artisan، هنگامی که با این --event گزینه فراخوانی می شود، به طور خودکار کلاس رویداد مناسب را وارد می کند و رویداد را در متد تایپ می کند handle . در handle روش، می‌توانید هر اقدامی را که برای پاسخ دادن به رویداد لازم است انجام دهید:

<?php
 
namespace App\Listeners;
 
use App\Events\OrderShipped;
 
class SendShipmentNotification
{
/**
* Create the event listener.
*/
public function __construct()
{
// ...
}
 
/**
* Handle the event.
*/
public function handle(OrderShipped $event): void
{
// Access the order using $event->order...
}
}

شنوندگان رویداد شما همچنین ممکن است هر گونه وابستگی را که به سازنده خود نیاز دارند تایپ کنند. همه شنوندگان رویداد از طریق ظرف سرویس لاراول حل می شوند ، بنابراین وابستگی ها به طور خودکار تزریق می شوند.

توقف انتشار یک رویداد

گاهی اوقات، ممکن است بخواهید انتشار یک رویداد را برای شنوندگان دیگر متوقف کنید. شما می توانید این کار را با بازگشت false از روش شنونده خود انجام دهید handle .

شنوندگان رویداد در صف

اگر شنونده شما قرار است کارهای کندی مانند ارسال ایمیل یا درخواست HTTP انجام دهد، قرار دادن شنوندگان در صف می تواند مفید باشد. قبل از استفاده از شنوندگان در صف، مطمئن شوید که صف خود را پیکربندی کرده و یک queue worker در سرور یا محیط توسعه محلی خود راه اندازی کنید.

برای تعیین اینکه شنونده باید در صف قرار گیرد، ShouldQueue رابط را به کلاس listener اضافه کنید. شنوندگان تولید شده توسط make:listener دستورات Artisan قبلاً این رابط را به فضای نام فعلی وارد کرده اند، بنابراین می توانید بلافاصله از آن استفاده کنید:

<?php
 
namespace App\Listeners;
 
use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
 
class SendShipmentNotification implements ShouldQueue
{
// ...
}

خودشه! اکنون، هنگامی که رویدادی که توسط این شنونده مدیریت می شود ارسال می شود، شنونده به طور خودکار توسط توزیع کننده رویداد با استفاده از سیستم صف لاراول در صف قرار می گیرد . اگر هنگام اجرای شنونده توسط صف، هیچ استثنایی وجود نداشته باشد، کار در صف به طور خودکار پس از پایان پردازش حذف می شود.

سفارشی کردن اتصال صف، نام، و تاخیر

اگر می‌خواهید اتصال صف، نام صف، یا زمان تأخیر صف شنونده رویداد را سفارشی کنید، می‌توانید $connection , $queue یا $delay ویژگی‌ها را در کلاس شنونده خود تعریف کنید:

<?php
 
namespace App\Listeners;
 
use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
 
class SendShipmentNotification implements ShouldQueue
{
/**
* The name of the connection the job should be sent to.
*
* @var string|null
*/
public $connection = 'sqs';
 
/**
* The name of the queue the job should be sent to.
*
* @var string|null
*/
public $queue = 'listeners';
 
/**
* The time (seconds) before the job should be processed.
*
* @var int
*/
public $delay = 60;
}

اگر می‌خواهید اتصال صف شنونده، نام صف یا تأخیر در زمان اجرا را تعریف کنید، می‌توانید viaConnection , viaQueue یا withDelay متدهایی را در شنونده تعریف کنید:

/**
* Get the name of the listener's queue connection.
*/
public function viaConnection(): string
{
return 'sqs';
}
 
/**
* Get the name of the listener's queue.
*/
public function viaQueue(): string
{
return 'listeners';
}
 
/**
* Get the number of seconds before the job should be processed.
*/
public function withDelay(OrderShipped $event): int
{
return $event->highPriority ? 0 : 60;
}

شنوندگان در صف مشروط

گاهی اوقات، ممکن است لازم باشد تعیین کنید که آیا شنونده باید بر اساس برخی از داده هایی که فقط در زمان اجرا در دسترس هستند در صف قرار گیرد یا خیر. برای انجام این کار، shouldQueue ممکن است روشی به شنونده اضافه شود تا مشخص شود آیا شنونده باید در صف قرار گیرد یا خیر. اگر shouldQueue متد برگردد false ، شنونده اجرا نخواهد شد:

<?php
 
namespace App\Listeners;
 
use App\Events\OrderCreated;
use Illuminate\Contracts\Queue\ShouldQueue;
 
class RewardGiftCard implements ShouldQueue
{
/**
* Reward a gift card to the customer.
*/
public function handle(OrderCreated $event): void
{
// ...
}
 
/**
* Determine whether the listener should be queued.
*/
public function shouldQueue(OrderCreated $event): bool
{
return $event->order->subtotal >= 5000;
}
}

تعامل دستی با صف

delete اگر نیاز دارید که به صورت دستی به کارها و روش‌های صف زیربنایی شنونده دسترسی داشته باشید release ، ممکن است این کار را با استفاده از ویژگی انجام دهید Illuminate\Queue\InteractsWithQueue . این ویژگی به طور پیش‌فرض در شنوندگان تولید شده وارد می‌شود و دسترسی به این روش‌ها را فراهم می‌کند:

<?php
 
namespace App\Listeners;
 
use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
 
class SendShipmentNotification implements ShouldQueue
{
use InteractsWithQueue;
 
/**
* Handle the event.
*/
public function handle(OrderShipped $event): void
{
if (true) {
$this->release(30);
}
}
}

شنوندگان رویداد در صف و معاملات پایگاه داده

هنگامی که شنوندگان صف در داخل تراکنش های پایگاه داده ارسال می شوند، ممکن است قبل از انجام تراکنش پایگاه داده توسط صف پردازش شوند. هنگامی که این اتفاق می افتد، هر به روز رسانی که در طول تراکنش پایگاه داده در مدل ها یا رکوردهای پایگاه داده انجام داده اید ممکن است هنوز در پایگاه داده منعکس نشود. علاوه بر این، هر مدل یا رکورد پایگاه داده ایجاد شده در تراکنش ممکن است در پایگاه داده وجود نداشته باشد. اگر شنونده شما به این مدل ها وابسته است، هنگام پردازش کاری که شنونده در صف را ارسال می کند، خطاهای غیرمنتظره ای رخ می دهد.

اگر گزینه پیکربندی اتصال صف شما after_commit روی تنظیم شده باشد ، همچنان ممکن است نشان دهید که یک شنونده در صف خاص باید پس از انجام تمام تراکنش‌های پایگاه داده باز با پیاده‌سازی رابط در کلاس listener false ارسال شود : ShouldHandleEventsAfterCommit

<?php
 
namespace App\Listeners;
 
use Illuminate\Contracts\Events\ShouldHandleEventsAfterCommit;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
 
class SendShipmentNotification implements ShouldQueue, ShouldHandleEventsAfterCommit
{
use InteractsWithQueue;
}

برای کسب اطلاعات بیشتر در مورد کار در مورد این مسائل، لطفاً اسناد مربوط به مشاغل در صف و تراکنش های پایگاه داده را مرور کنید .

رسیدگی به مشاغل ناموفق

گاهی اوقات ممکن است شنوندگان رویداد در صف شما شکست بخورند. اگر شنونده در صف از حداکثر تعداد تلاش های تعریف شده توسط کارگر صف شما بیشتر شود، متد failed در شنونده شما فراخوانی می شود. متد failed نمونه رویداد و مواردی Throwable که باعث شکست شده است را دریافت می کند:

<?php
 
namespace App\Listeners;
 
use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Throwable;
 
class SendShipmentNotification implements ShouldQueue
{
use InteractsWithQueue;
 
/**
* Handle the event.
*/
public function handle(OrderShipped $event): void
{
// ...
}
 
/**
* Handle a job failure.
*/
public function failed(OrderShipped $event, Throwable $exception): void
{
// ...
}
}

تعیین حداکثر تلاش شنونده در صف

اگر یکی از شنوندگان در صف شما با خطا مواجه شد، احتمالاً نمی‌خواهید که به طور نامحدود به تلاش مجدد ادامه دهد. بنابراین، لاراول راه های مختلفی را برای تعیین چند بار یا مدت زمان تلاش برای شنونده ارائه می دهد.

شما می توانید یک $tries ویژگی را در کلاس listener خود تعریف کنید تا مشخص کنید چند بار ممکن است شنونده قبل از اینکه شکست خورده در نظر گرفته شود تلاش شود:

<?php
 
namespace App\Listeners;
 
use App\Events\OrderShipped;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
 
class SendShipmentNotification implements ShouldQueue
{
use InteractsWithQueue;
 
/**
* The number of times the queued listener may be attempted.
*
* @var int
*/
public $tries = 5;
}

به عنوان جایگزینی برای تعریف اینکه چند بار ممکن است یک شنونده قبل از شکست آن تلاش شود، ممکن است زمانی را تعریف کنید که در آن شنونده دیگر نباید تلاش کند. این به شنونده اجازه می دهد تا هر تعداد بار در یک بازه زمانی معین تلاش کند. برای تعیین زمانی که در آن شنونده دیگر نباید تلاش کرد، یک retryUntil متد به کلاس شنونده خود اضافه کنید. این متد باید یک DateTime نمونه برگرداند :

use DateTime;
 
/**
* Determine the time at which the listener should timeout.
*/
public function retryUntil(): DateTime
{
return now()->addMinutes(5);
}

اعزام رویدادها

برای ارسال یک رویداد، می توانید dispatch متد استاتیک را در رویداد فراخوانی کنید. این روش در رویداد توسط Illuminate\Foundation\Events\Dispatchable صفت در دسترس قرار می گیرد. هر آرگومان ارسال شده به dispatch متد به سازنده رویداد ارسال می شود:

<?php
 
namespace App\Http\Controllers;
 
use App\Events\OrderShipped;
use App\Http\Controllers\Controller;
use App\Models\Order;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
 
class OrderShipmentController extends Controller
{
/**
* Ship the given order.
*/
public function store(Request $request): RedirectResponse
{
$order = Order::findOrFail($request->order_id);
 
// Order shipment logic...
 
OrderShipped::dispatch($order);
 
return redirect('/orders');
}
}

اگر می‌خواهید رویدادی را به صورت مشروط ارسال کنید، می‌توانید از روش‌های dispatchIf و استفاده کنید dispatchUnless :

OrderShipped::dispatchIf($condition, $order);
 
OrderShipped::dispatchUnless($condition, $order);

هنگام آزمایش، می‌توان گفت که برخی رویدادها بدون تحریک شنوندگان ارسال شده‌اند. کمک‌های آزمایشی داخلی لاراول، آن را بسیار جذاب کرده است.

ارسال رویدادها پس از تراکنش های پایگاه داده

گاهی اوقات، ممکن است بخواهید به لاراول دستور دهید تا یک رویداد را فقط پس از انجام تراکنش فعال پایگاه داده ارسال کند. برای انجام این کار، می توانید ShouldDispatchAfterCommit اینترفیس را در کلاس رویداد پیاده سازی کنید.

این رابط به لاراول دستور می دهد تا زمانی که تراکنش فعلی پایگاه داده انجام نشود، رویداد را ارسال نکند. اگر تراکنش با شکست مواجه شود، رویداد کنار گذاشته می شود. اگر هنگام ارسال رویداد هیچ تراکنش پایگاه داده در حال انجام نباشد، رویداد بلافاصله ارسال می شود:

<?php
 
namespace App\Events;
 
use App\Models\Order;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Events\ShouldDispatchAfterCommit;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
 
class OrderShipped implements ShouldDispatchAfterCommit
{
use Dispatchable, InteractsWithSockets, SerializesModels;
 
/**
* Create a new event instance.
*/
public function __construct(
public Order $order,
) {}
}

مشترکین رویداد

نوشتن مشترکین رویداد

مشترکین رویداد کلاس هایی هستند که ممکن است در چندین رویداد از درون خود کلاس مشترک مشترک شوند و به شما امکان می دهند چندین کنترل کننده رویداد را در یک کلاس واحد تعریف کنید. مشترکین باید subscribe روشی را تعریف کنند که به یک نمونه توزیع کننده رویداد ارسال می شود. برای ثبت شنوندگان رویداد می توانید listen متد موجود در توزیع کننده داده شده را فراخوانی کنید:

<?php
 
namespace App\Listeners;
 
use Illuminate\Auth\Events\Login;
use Illuminate\Auth\Events\Logout;
use Illuminate\Events\Dispatcher;
 
class UserEventSubscriber
{
/**
* Handle user login events.
*/
public function handleUserLogin(Login $event): void {}
 
/**
* Handle user logout events.
*/
public function handleUserLogout(Logout $event): void {}
 
/**
* Register the listeners for the subscriber.
*/
public function subscribe(Dispatcher $events): void
{
$events->listen(
Login::class,
[UserEventSubscriber::class, 'handleUserLogin']
);
 
$events->listen(
Logout::class,
[UserEventSubscriber::class, 'handleUserLogout']
);
}
}

اگر روش‌های شنونده رویداد شما در خود مشترک تعریف شده‌اند، ممکن است برای شما راحت‌تر باشد که مجموعه‌ای از رویدادها و نام‌های روش را از متد مشترک برگردانید subscribe . لاراول به طور خودکار نام کلاس مشترک را هنگام ثبت شنوندگان رویداد تعیین می کند:

<?php
 
namespace App\Listeners;
 
use Illuminate\Auth\Events\Login;
use Illuminate\Auth\Events\Logout;
use Illuminate\Events\Dispatcher;
 
class UserEventSubscriber
{
/**
* Handle user login events.
*/
public function handleUserLogin(Login $event): void {}
 
/**
* Handle user logout events.
*/
public function handleUserLogout(Logout $event): void {}
 
/**
* Register the listeners for the subscriber.
*
* @return array<string, string>
*/
public function subscribe(Dispatcher $events): array
{
return [
Login::class => 'handleUserLogin',
Logout::class => 'handleUserLogout',
];
}
}

ثبت نام مشترکین رویداد

پس از نوشتن مشترک، آماده ثبت آن در دیسپچر رویداد هستید. شما می توانید با استفاده از subscribe روش نما مشترکین را ثبت کنید Event . به طور معمول، این باید در boot روش برنامه شما انجام شود AppServiceProvider :

<?php
 
namespace App\Providers;
 
use App\Listeners\UserEventSubscriber;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\ServiceProvider;
 
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Event::subscribe(UserEventSubscriber::class);
}
}

آزمایش کردن

هنگام آزمایش کدی که رویدادها را ارسال می کند، ممکن است بخواهید به لاراول دستور دهید که واقعاً شنوندگان رویداد را اجرا نکند، زیرا کد شنونده را می توان به طور مستقیم و جدا از کدی که رویداد مربوطه را ارسال می کند آزمایش کرد. البته، برای آزمایش خود شنونده، می‌توانید نمونه شنونده را نمونه‌سازی کنید و handle مستقیماً از روش در آزمون خود استفاده کنید.

با استفاده از روش Event نما fake ، می‌توانید از اجرای شنوندگان جلوگیری کنید، کد مورد آزمایش را اجرا کنید و سپس با استفاده از روش‌های، و و مشخص کنید که کدام رویدادها توسط برنامه شما ارسال assertDispatched شده assertNotDispatched است assertNothingDispatched :

<?php
 
use App\Events\OrderFailedToShip;
use App\Events\OrderShipped;
use Illuminate\Support\Facades\Event;
 
test('orders can be shipped', function () {
Event::fake();
 
// Perform order shipping...
 
// Assert that an event was dispatched...
Event::assertDispatched(OrderShipped::class);
 
// Assert an event was dispatched twice...
Event::assertDispatched(OrderShipped::class, 2);
 
// Assert an event was not dispatched...
Event::assertNotDispatched(OrderFailedToShip::class);
 
// Assert that no events were dispatched...
Event::assertNothingDispatched();
});
<?php
 
namespace Tests\Feature;
 
use App\Events\OrderFailedToShip;
use App\Events\OrderShipped;
use Illuminate\Support\Facades\Event;
use Tests\TestCase;
 
class ExampleTest extends TestCase
{
/**
* Test order shipping.
*/
public function test_orders_can_be_shipped(): void
{
Event::fake();
 
// Perform order shipping...
 
// Assert that an event was dispatched...
Event::assertDispatched(OrderShipped::class);
 
// Assert an event was dispatched twice...
Event::assertDispatched(OrderShipped::class, 2);
 
// Assert an event was not dispatched...
Event::assertNotDispatched(OrderFailedToShip::class);
 
// Assert that no events were dispatched...
Event::assertNothingDispatched();
}
}

assertDispatched شما می‌توانید روش‌های یا روش‌های بسته را بگذرانید assertNotDispatched تا ادعا کنید رویدادی ارسال شده است که یک "آزمون حقیقت" معین را گذرانده است. اگر حداقل یک رویداد ارسال شده باشد که آزمون صدق داده شده را با موفقیت پشت سر بگذارد، ادعا موفقیت آمیز خواهد بود:

Event::assertDispatched(function (OrderShipped $event) use ($order) {
return $event->order->id === $order->id;
});

اگر به سادگی می خواهید ادعا کنید که شنونده رویداد در حال گوش دادن به یک رویداد خاص است، می توانید از assertListening روش زیر استفاده کنید:

Event::assertListening(
OrderShipped::class,
SendShipmentNotification::class
);

پس از تماس Event::fake() ، هیچ شنونده رویدادی اجرا نمی شود. بنابراین، اگر آزمایش‌های شما از کارخانه‌های مدل استفاده می‌کنند که به رویدادها متکی هستند، مانند ایجاد UUID در طول creating رویداد یک مدل، باید Event::fake() پس از استفاده از کارخانه‌های خود تماس بگیرید.

جعل کردن زیر مجموعه ای از رویدادها

اگر فقط می خواهید شنوندگان رویداد را برای مجموعه خاصی از رویدادها جعل کنید، می توانید آنها را به روش fake یا ارسال کنید fakeFor :

test('orders can be processed', function () {
Event::fake([
OrderCreated::class,
]);
 
$order = Order::factory()->create();
 
Event::assertDispatched(OrderCreated::class);
 
// Other events are dispatched as normal...
$order->update([...]);
});
/**
* Test order process.
*/
public function test_orders_can_be_processed(): void
{
Event::fake([
OrderCreated::class,
]);
 
$order = Order::factory()->create();
 
Event::assertDispatched(OrderCreated::class);
 
// Other events are dispatched as normal...
$order->update([...]);
}

شما می توانید همه رویدادها را جعل کنید به جز مجموعه ای از رویدادهای مشخص شده با استفاده از except روش:

Event::fake()->except([
OrderCreated::class,
]);

تقلبی رویدادهای محدوده

اگر فقط می خواهید شنوندگان رویداد را برای بخشی از آزمایش خود جعل کنید، می توانید از fakeFor روش زیر استفاده کنید:

<?php
 
use App\Events\OrderCreated;
use App\Models\Order;
use Illuminate\Support\Facades\Event;
 
test('orders can be processed', function () {
$order = Event::fakeFor(function () {
$order = Order::factory()->create();
 
Event::assertDispatched(OrderCreated::class);
 
return $order;
});
 
// Events are dispatched as normal and observers will run ...
$order->update([...]);
});
<?php
 
namespace Tests\Feature;
 
use App\Events\OrderCreated;
use App\Models\Order;
use Illuminate\Support\Facades\Event;
use Tests\TestCase;
 
class ExampleTest extends TestCase
{
/**
* Test order process.
*/
public function test_orders_can_be_processed(): void
{
$order = Event::fakeFor(function () {
$order = Order::factory()->create();
 
Event::assertDispatched(OrderCreated::class);
 
return $order;
});
 
// Events are dispatched as normal and observers will run ...
$order->update([...]);
}
}