php Laravel Queue::fake()应该在我们的测试中排在首位吗?

csga3l58  于 2023-09-29  发布在  PHP
关注(0)|答案(1)|浏览(98)

这是一个非常简单的问题,我做了这个测试:

public function test_expired_cases_empty_dont_dispatch_update_expired_class()
{
    $this->expired1->created_at = Carbon::now();
    $this->expired1->save();
    $this->expired2->created_at = Carbon::now()->subDays(30);
    $this->expired2->save();

    Queue::fake();

    $this->artisan('expiration:update-expired')->assertSuccessful();

    Queue::assertNotPushed(UpdateExpired::class);
}

所以基本上,expiration:update-expired命令只是检查我是否有过期的案例,标准是'created_at', '<', Carbon::now()->subDays(30),所以测试中的案例不应该被视为过期,基本上测试随机失败并返回The unexpected [App\Jobs\UpdateExpired] job was pushed,我认为问题是调用Queue::fake();时有1或2秒的延迟,因此,当调用该命令时,expired2情况实际上已过期。
所以,我的问题是,这个方法应该在测试的顶部,以确保测试不会返回这种随机失败?

qacovj5a

qacovj5a1#

您的问题是一个计时问题,而不是Queue::fake();,因此将其放在第一行或在调用命令之前都没有关系,您必须冻结时间。
根据你的Laravel版本(9+),你可以冻结时间,这样它就不会在你运行测试时继续前进,这正是你所需要的。
你的测试应该是这样的:

public function test_expired_cases_empty_dont_dispatch_update_expired_class()
{
    $this->travelTo(now()->addSecond());

    $this->expired1->created_at = now();
    $this->expired1->save();

    $this->expired2->created_at = now()->subDays(30);
    $this->expired2->save();

    Queue::fake();

    $this->artisan('expiration:update-expired')->assertSuccessful();

    Queue::assertNotPushed(UpdateExpired::class);
}

您可以使用$this->travelTo(now()->addSecond());的不同变体(查看我附带的文档链接,并使用解决您的问题的文档链接)。我还将Carbon::now()替换为now()
如果这对你不起作用,请告诉我,但这应该是你的解决方案。
请记住,Queue::fake();与时间无关,如果您首先运行它或在命令之前运行它,在这种情况下不会发生任何变化。

相关问题