如何使用 Carbon::setTestNow() 影响 FakerPHP dateTimeBetween 方法的结果?

问题描述 投票:0回答:1

我在 Laravel 测试套件中使用返回日期范围的模型工厂方法。例如:

class WorkSiteFactory extends Factory
{
  // ... Other factory stuff....

  /**
  * Indicate that the Permit status is fully approved.
  */
  public function withApprovedPermit(): self
  {
      return $this->state([
        'permit_paid_at' => $this->faker->dateTimeBetween('-12 days', '-8 days'),
        'permit_approved_at' => $this->faker->dateTimeBetween('-12 days', '-8 days')
      ]);
  }
}

在测试中,我有时会使用

Carbon::setTestNow()
模拟日期,然后做出测试断言。但不幸的是
dateTimeBetween
用法不会响应模拟日期。

use App\Models\WorkSite;
use Illuminate\Support\Carbon;
use Tests\TestCase;

class SchedulerControllerTest extends TestCase
{

    /** @test */
    public function index_returns_correct_number_of_work_sites(): void
    {  
        // Set the mocked "now" time
        $mockNow = Carbon::parse('2024-10-01');
        Carbon::setTestNow($mockNow);
    

        // Incomplete WorkSites won't show up as available
        WorkSite::factory()
            ->count(2)
            ->incomplete()
            ->create();
         
        // 4 WorkSites Ready to Work
        $workSites = WorkSite::factory()
            ->count(4)
            ->readyToWork() 
            ->withApprovedPermit() // ❌ <- this should set the permit dates correctly but it doesn't adjust according to the mocked date
            ->create();

        $response = $this
            ->actingAs(User::factory()->create())
            ->get(route('scheduler.index'))
            ->assertOk();

        // Then asserting that the right number of
        // WorkSites are returned according to the date...
        // ...
    }
}

我做了一些源代码挖掘,并认为也许有一种方法可以覆盖 Faker 包中的“now”,但我没有看到任何方法。

我还尝试将返回值包装在

Carbon::instance()
Carbon::parse()
中,但都不起作用。

我确信有一种奇怪的方法可以编写一个方法,该方法获取 Faker 的结果并根据

Carbon::now()
时间进行调整,但这似乎是错误的解决方案。

提前致谢!

php laravel testing php-carbon faker
1个回答
0
投票

Faker 使用 PHP 的 DateTime 类,并且不以任何方式使用 Carbon(它扩展了 DateTime)。

由于模型工厂仅在测试套件中使用,因此您可以向 withApprovedPermit() 添加一个参数,您可以在其中提供 DateTime 对象。

或者您可以在创建后手动设置对象的日期(前提是您有所需的设置器)

© www.soinside.com 2019 - 2024. All rights reserved.