Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як тестувати код, що залежить від поточного часу?

Керувати часом застосунку з тесту, а не чекати.

it('expires a subscription after 30 days', function () {
    $this->freezeTime();

    $subscription = Subscription::factory()->create();

    $this->travel(31)->days();

    expect($subscription->fresh()->isExpired())->toBeTrue();
});

Інструменти:

  • freezeTime() - зупиняє now(), щоб час не зсувався між рядками тесту.
  • travel(5)->minutes(), travelTo($date), travelBack() - зсувають час застосунку.
  • Те саме вміє Carbon::setTestNow().

Що варто винести з цього: такий тест працює, лише поки код бере час через now() чи Carbon. Виклики time(), date() чи new \DateTime() бачать справжній годинник і тест обійдуть.

Чистіший шлях для доменного коду - передавати момент явно:

public function isExpired(CarbonImmutable $now): bool
{
    return $this->ends_at->lessThan($now);
}

Тоді тест взагалі не потребує підміни часу, а метод стає чистою функцією. Корисні випадки для перевірки: межі (рівно 30 днів), перехід доби, часові пояси й літній час.

Докладніше в документації: Робота з часом

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання