Проверка того, какая очередь была отправлена, какое событие или уведомление было разослано, обычно требует написания callback-функции, сравнивающей каждое свойство. Начиная с Laravel 13.35, заглушки (fakes)  Queue ,  Bus ,  Event  и  Notification  принимают массив ожидаемых значений свойств вместо этой callback-функции.

#До и после

Рассмотрим тест для загрузки подкаста, который отправляет задачу  ProcessPodcast . До версии 13.35 проверка свойств задачи требовала использования callback-функции:

Queue::fake();
 
$this->actingAs($user)->post('/podcasts', $data);
 
Queue::assertPushed(ProcessPodcast::class, function (ProcessPodcast $job) use ($podcast, $user) {
    return $job->podcast->is($podcast)
        && $job->user->is($user)
        && $job->status === 'pending';
});
 

Начиная с версии 13.35, ожидаемые значения передаются в виде массива:

Queue::assertPushed(ProcessPodcast::class, [
    'podcast' => $podcast,
    'user' => $user,
    'status' => 'pending',
]);
 

Остальные заглушки работают аналогичным образом:

Event::assertDispatched(OrderShipped::class, ['order' => $order]);
 
Bus::assertDispatched(GenerateInvoice::class, ['order' => $order]);
 
Notification::assertSentTo($user, InvoicePaid::class, ['invoice' => $invoice]);
 

Этот массив также работает с отрицательными и альтернативными вариантами утверждений (assertions), принимающими callback, такими как  assertNotPushed() ,  assertPushedOn() ,  assertNotDispatched()  и  assertNotSentTo() :

Queue::assertNotPushed(ProcessPodcast::class, ['user' => $otherUser]);
 

Передайте имя класса в качестве первого аргумента. Массив нельзя использовать с той формой  assertPushed() , которая принимает только замыкание с типом (typed closure).

#Как сравниваются значения

Для успешного прохождения утверждения должны совпадать все ключи в массиве. Каждое значение сравнивается с использованием строгого равенства ( === ), за исключением одного случая: когда и ожидаемое, и фактическое значения являются моделями Eloquent, они сравниваются с помощью  $model->is() , который проверяет первичный ключ, таблицу и соединение.

Строгое равенство имеет последствия для других объектов. Два экземпляра  Carbon  для одного и того же момента времени являются разными объектами, поэтому  'scheduled_at' => now()  завершится с ошибкой. Используйте callback, когда вам нужно сравнить даты, объекты-значения (value objects) или коллекции:

Queue::assertPushed(SendReminder::class, function (SendReminder $job) use ($user) {
    return $job->user->is($user)
        && $job->sendAt->equalTo(now()->addDay());
});
 

Массив проверяет только свойства верхнего уровня, поэтому вложенные значения через точечную нотацию (dot notation) не поддерживаются.

#Только публичные свойства

Заглушка считывает каждое свойство извне объекта, поэтому свойства должны быть публичными. Задаче, которая хранит свои данные в свойствах  protected  или за методами-геттерами, по-прежнему требуется callback. Повышение видимости свойств в конструкторе (constructor property promotion) с помощью  public  работает:

class ProcessPodcast implements ShouldQueue
{
    use Queueable;
 
    public function __construct(
        public Podcast $podcast,
        public User $user,
        public string $status = 'pending',
    ) {}
}
 

Ключ, которого нет у объекта, приводит к провалу утверждения вместо выброса ошибки, поэтому опечатка в имени свойства отобразится как неудачный тест.

#Дополнительное чтение

Jack Bayliss внес свой вклад в изменение в #61770.