Summer Sale! All accounts are 50% off this week.

nfauchelle's avatar

Bus::fake() vs Queue::fake()

Upgrading a Laravel app and the expectsJobs /doesntExpectJobs methods are no longer supported in tests.

This is covered in the upgrade notes and I notice it mentions to use Bus:fake() https://laravel.com/docs/10.x/upgrade#service-mocking

But then checking the docs we have https://laravel.com/docs/11.x/queues#testing But then https://laravel.com/docs/11.x/queues#testing-job-chains is for batches

I guess, without digging into the code I don't really se which way I should be going.

Bus fake, or Queue fake....

0 likes
1 reply
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

When deciding whether to use Bus::fake() or Queue::fake() in your tests, it's important to understand the context in which each should be used.

Bus::fake() is used for faking the dispatching of jobs, events, and commands. This is useful when you want to ensure that a job or command is dispatched without actually executing its logic. It's also the way to go when you're dealing with job chains or batches, as the Bus facade is responsible for handling these advanced job features.

Queue::fake(), on the other hand, is specifically for faking queue jobs. When you're only interested in testing the queuing of jobs and not the other features of the Bus facade, Queue::fake() is the appropriate choice.

Here's how you can use each in your tests:

Using Bus::fake():

use Illuminate\Support\Facades\Bus;
use App\Jobs\ProcessPodcast;

public function test_podcast_process_is_dispatched()
{
    Bus::fake();

    // Perform order shipping...

    // Assert that a job was dispatched...
    Bus::assertDispatched(ProcessPodcast::class);

    // Assert that a job was not dispatched...
    Bus::assertNotDispatched(AnotherJob::class);
}

Using Queue::fake():

use Illuminate\Support\Facades\Queue;
use App\Jobs\ProcessPodcast;

public function test_podcast_process_is_queued()
{
    Queue::fake();

    // Perform order shipping...

    // Assert that a job was pushed onto the queue...
    Queue::assertPushed(ProcessPodcast::class);

    // Assert that a job was not pushed onto the queue...
    Queue::assertNotPushed(AnotherJob::class);
}

In summary, if you're testing job dispatching in general, including job chains and batches, you should use Bus::fake(). If you're only interested in testing the queuing of jobs, Queue::fake() is sufficient.

Since the expectsJobs and doesntExpectJobs methods are no longer supported, you would replace them with Bus::assertDispatched and Bus::assertNotDispatched respectively when using Bus::fake(), or with Queue::assertPushed and Queue::assertNotPushed when using Queue::fake().

Choose the one that best fits the scope of what you're trying to test in your Laravel application.

Please or to participate in this conversation.