首页 > 解决方案 > 作业在测试期间错误地显示为已调度

问题描述

我有以下测试用例:

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);
}

只是向updateModel控制器推送一个发布请求。请求由以下方法处理:

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);
}

很明显,我正在测试的是该作业不会被推送到队列中。但是,我的最终测试失败了:

  The unexpected [App\Jobs\MyJob] job was pushed.
  Failed asserting that actual size 1 matches expected size 0.

我已通过dump()声明确认在第三次测试期间该工作没有被推动。通过交换第二个和第三个测试,测试套件成功通过,这表明在第二个测试中推入队列的作业已经持续到第三个测试。

我正在使用database队列驱动程序(QUEUE_CONNECTION=databasein .env.testing)并将RefreshDatabase特征导入到我的测试类中。这应该会在测试之间删除数据库,但似乎不是。

当我尝试手动清除队列时,我得到:

Call to undefined method Illuminate\Support\Testing\Fakes\QueueFake::clear()

有没有办法清除setUp方法中的队列?我应该以不同的方式处理这个问题吗?

标签: phplaraveltestingphpunitlaravel-jobs

解决方案


由于缺少该(重要)部分,因此请确保您同时执行以下操作:

[...] 并且 RefreshDatabase 特征被导入到我的测试类中。

您是只导入它还是同时使用它?您的 TestClass 需要看起来像这样:

<?php

[..]

use Illuminate\Foundation\Testing\RefreshDatabase;

[..]

class YourTest extends TestCase
{
    use RefreshDatabase;

    [..]
   
}

推荐阅读