Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ddesyllas's avatar

Why I am unable to assert that a job has not been dispatched?

I have the following job:

namespace App\Jobs;

use App\Jobs\AnothertJob;

class MyJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function handle()
    {
        AnothertJob::dispatchNow();
    }
} 

And I have the AnothertJob as well:

namespace App\Jobs;


class AnothertJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
    public function handle()
    {
    }
}

And I try to test the MyJob job like this:

namespace Test\Jobs;

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

public function MyJobTest extends TestCase
{
   public function testDispatchesAnotherJob()
   {
       Bus::fake();
       MyJob::dispatch();
       Bus::assertDispatched(AnothertJob::class);
   }
}

But I get the following error:

F                                                                   1 / 1 (100%)

Time: 6.31 seconds, Memory: 40.00 MB

There was 1 failure:

1) Tests\Jobs\MyJobTest::testDispatchesAnotherJob
The expected [App\Jobs\AnothertJob] job was not dispatched.
Failed asserting that false is true.

/var/www/html/api/vendor/laravel/framework/src/Illuminate/Support/Testing/Fakes/BusFake.php:32
/var/www/html/api/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:237
/var/www/html/api/tests/Jobs/MyJobTest.php:10

The laravel version is the 5.7 one (Yes we are using an old version of the laravel in my job) and I have trouble to assert that a job has been dispatched.

I also tried to use theQueue::fake as well but still fail to assert that a job has been dispatched as well:

namespace Test\Jobs;

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

public function MyJobTest extends TestCase
{
   public function testDispatchesAnotherJob()
   {
       Queue::fake();
       MyJob::dispatch();
       Queue::assertPushed(AnothertJob::class);
   }
}
0 likes
9 replies
bugsysha's avatar

Because you are already not dispatching your first job. The logic for dispatching gets faked and you can only assert that the first job was dispatched.

ddesyllas's avatar

So how I can assert that a job dispatches an another job?

geneowak's avatar

@ddesyllas you can do that by calling the handle method on the job because if you dispatch it it won't work process because you have already called the fake on the Queue/Bus which stops the job processing. I think something like this should work

namespace Test\Jobs;

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

public function MyJobTest extends TestCase
{
   public function testDispatchesAnotherJob()
   {
       Queue::fake();
       (new MyJob())->handle();
       Queue::assertPushed(AnothertJob::class);
   }
}
bugsysha's avatar

Either use job chains (you can assert that) or test your job and assert that it dispatched the job (which I do not recommend).

// Assert a job was pushed with a specific chain...
\Illuminate\Support\Facades\Queue::assertPushedWithChain(ShipOrder::class, [
    AnotherJob::class,
    FinalJob::class
]);
ddesyllas's avatar

So how I can launch the queue worker so it can read the appropriate settings from phpunit.xml so it can run the job dispatches in an isolated environment?

bugsysha's avatar

You do not run the queue worker when running the tests.

ddesyllas's avatar

But I can do it via exec('php artisan queue:listen');

bugsysha's avatar

You do not need that. That is handled by the testing framework.

mix5003's avatar

i think you forgot this line in test file.

use App\Jobs\AnothertJob;

Please or to participate in this conversation.