Тестування
Queuety надає клас QueueFake, який замінює реальну чергу сховищем у пам’яті. Надіслані завдання записуються замість збереження в базі даних, а create_batch() також зберігає метадані пакетів у пам’яті. Це дає змогу перевіряти надсилання завдань без запуску робочих процесів і запису до бази даних. Надсилання за назвою обробника й далі шукає обробник у реєстрі, тому для надсилання з рядковою назвою обробника спершу викличте Queuety::init(); екземпляри Contracts\Job, chain(), create_batch() і batch() працюють без цього.
Налаштування підміни
Викличте Queuety::fake() на початку тесту. Він повертає екземпляр QueueFake, який записує всі наступні надсилання завдань.
use Queuety\Queuety;
class SendEmailTest extends \PHPUnit\Framework\TestCase {
protected function setUp(): void {
$this->fake = Queuety::fake();
}
protected function tearDown(): void {
Queuety::reset();
}
}
Queuety::fake() створює новий QueueFake і підключає його до фасаду Queuety. Queuety::dispatch() і Dispatchable::dispatch() записують додані завдання. Queuety::chain() записує кожне завдання в ланцюжку як звичайне додавання у порядку надсилання. Queuety::create_batch() записує як додані завдання, так і метадані пакета, які використовує assert_batched(). Queuety::batch() записує додані завдання, але не створює фальшивих метаданих пакета.
Викличте Queuety::reset() у tearDown(), щоб очистити підміну між тестами. Він очищає весь стан фасаду, тож викличте Queuety::init() ще раз, якщо в наступному тесті потрібна реальна черга.
Перевірка додавання завдань
assert_pushed()
Перевірте, що завдання певного класу було надіслано принаймні один раз.
public function test_welcome_email_is_sent(): void {
$this->fake = Queuety::fake();
// Code under test...
register_new_user( 'user@example.com' );
$this->fake->assert_pushed( SendWelcomeEmailJob::class );
}
Передайте необов’язкову функцію зворотного виклику, щоб фільтрувати за даними або іншими атрибутами. Вона отримує масив записаних даних завдання з ключами handler, payload, queue і instance. Для завдань, надісланих через фасад або трейт Dispatchable, значенням instance є null, тому шукайте за handler і payload.
$this->fake->assert_pushed( SendWelcomeEmailJob::class, function ( array $job ) {
return $job['payload']['to'] === 'user@example.com';
} );
assert_pushed_times()
Перевірте, що завдання було додано точно задану кількість разів.
$this->fake->assert_pushed_times( SendEmailJob::class, 3 );
assert_not_pushed()
Перевірте, що завдання не надсилалося жодного разу.
$this->fake->assert_not_pushed( DeleteAccountJob::class );
assert_nothing_pushed()
Перевірте, що не було надіслано жодного завдання.
public function test_no_jobs_on_invalid_input(): void {
$this->fake = Queuety::fake();
process_input( '' ); // invalid, should not dispatch anything
$this->fake->assert_nothing_pushed();
}
Перевірка пакетів
assert_batched()
Перевірте, що пакет було надіслано. За бажанням передайте функцію зворотного виклику, щоб фільтрувати за вмістом пакета.
$this->fake->assert_batched();
$this->fake->assert_batched( function ( array $batch ) {
return count( $batch['jobs'] ) === 3;
} );
Функція зворотного виклику отримує масив із ключами jobs і options.
Перегляд доданих завдань
Використовуйте pushed(), щоб отримати всі записані надсилання для певного класу, а batches() — щоб отримати всі записані пакети.
$emails = $this->fake->pushed( SendEmailJob::class );
// [ ['handler' => '...', 'payload' => [...], 'queue' => 'default', 'instance' => null], ... ]
$batches = $this->fake->batches();
// [ ['jobs' => [...], 'options' => [...]], ... ]
Скидання між тестами
Викличте reset() для підміни, щоб очистити всі записані завдання та пакети без створення нового екземпляра.
$this->fake->reset();
Або викличте Queuety::reset(), щоб повністю завершити роботу підміни та очистити весь внутрішній стан.
Повний приклад
use PHPUnit\Framework\TestCase;
use Queuety\Queuety;
class OrderWorkflowTest extends TestCase {
private \Queuety\Testing\QueueFake $fake;
protected function setUp(): void {
$this->fake = Queuety::fake();
}
protected function tearDown(): void {
Queuety::reset();
}
public function test_order_dispatches_payment_job(): void {
$order = create_order( [ 'total' => 99.99 ] );
$this->fake->assert_pushed( ProcessPaymentJob::class, function ( array $job ) use ( $order ) {
return $job['payload']['order_id'] === $order->id;
} );
$this->fake->assert_not_pushed( RefundJob::class );
}
public function test_bulk_import_dispatches_batch(): void {
start_bulk_import( $rows );
$this->fake->assert_batched( function ( array $batch ) use ( $rows ) {
return count( $batch['jobs'] ) === count( $rows );
} );
}
public function test_nothing_dispatched_without_data(): void {
process_empty_queue();
$this->fake->assert_nothing_pushed();
}
}