I have the following test cases:
protected function setUp(): void
{
parent::setUp();
Queue::fake();
}
public function testUpdate(): void
{
$this->updateModel(["foo" => 123]);
$this->assertDatabaseHas("models", ["foo" => 123]);
}
public function testQueueJob(): void
{
$this->updateModel(["bar" => 456]);
$this->assertDatabaseHas("models", ["bar" => 456]);
$this->assertPushed(MyJob::class);
}
public function testDontQueueJob(): void
{
$this->updateModel(["baz" => 789]);
$this->assertDatabaseHas("models", ["baz" => 789]);
$this->assertNotPushed(MyJob::class);
}
The updateModel
just pushes out a post request to the controller. The request is handled by this method:
public method update(Request $request, Model $model): JsonResponse
{
$model->update($request->all());
$model->save();
if ($this->wasChanged("bar")) {
MyJob::dispatch($model);
}
return response()->json($model);
}
So obviously, what I'm testing is that the job doesn't get pushed onto the queue. However, my final test is failing with:
The unexpected [App\Jobs\MyJob] job was pushed.
Failed asserting that actual size 1 matches expected size 0.
I have confirmed with dump()
statements that the job is not being pushed during the third test. By swapping the second and third tests, the test suite passes successfully, suggesting that the job pushed onto the queue in the second test has persisted to the third test.
I am using the database
queue driver (QUEUE_CONNECTION=database
in .env.testing
) and the RefreshDatabase
trait is imported into my test class. This should erase the database between tests but it seems that it is not.
When I try clearing the queue manually, I get:
Call to undefined method Illuminate\Support\Testing\Fakes\QueueFake::clear()
Is there some way to clear the queue in the setUp
method? Is there a different way I should be handling this?