Skip to content

Test Mode

::test() executes the real code in a testable context. For queueable executables, it attaches a fake job so you can assert queue interactions (release, delete, fail, chain manipulation). For sync-only executables, it runs the code directly and queue assertions are not available.

php
it("releases the job when gateway is not ready", function () {
    $payment = Payment::factory()->create();
    Gateway::shouldBeUnavailable();

    ProcessPayment::test()->execute($payment);

    ProcessPayment::assert()->released(30);
    ProcessPayment::assert()->notDeleted();
    ProcessPayment::assert()->notFailed();
});

it("deletes jobs for expired payments", function () {
    $payment = Payment::factory()->expired()->create();

    ProcessPayment::test()->execute($payment);

    ProcessPayment::assert()->deleted();
});

it("fails job on invalid payment data", function () {
    $payment = Payment::factory()->invalid()->create();

    ProcessPayment::test()->execute($payment);

    ProcessPayment::assert()->failed();
});

it("builds a chain dynamically", function () {
    $order = Order::factory()->create();

    ProcessOrder::test()->execute($order);

    ProcessOrder::assert()->hasChain([SendConfirmation::class, UpdateInventory::class]);
});

Available Assertions

AssertionInverseWhat it checks
released(?$delay)notReleased()Job was released back to queue
deleted()notDeleted()Job was deleted
failed()notFailed()Job was manually failed
hasChain(array)hasNoChain()Chain attached to job

Single test() Per Test

test() can only be called once per test. It attaches a fake job to a singleton, so a second call would conflict with the first. If you need to run additional executables in the same test, use sync() for those. If you need to test two executables in test mode, split them into separate tests.