CloudCastle Clock

🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano

ClockSensitiveTrait — mocking time in PHPUnit

⚠️ Traducción preliminar: la versión rusa es la autoritativa; el contenido siguiente está por ahora en inglés.

Purpose

A trait for PHPUnit 10+ test cases: mockTime() puts a MockClock into the global clock, unmockTime() removes the substitution, and the #[Before]/#[After] hooks restore the original clock after every test. Parity with symfony ClockSensitiveTrait.

What for and how to use

Tests for code built on ClockHolder/DatePoint/Clock::now(): $clock = self::mockTime('2026-01-01 10:00'); $clock->sleep(60); — no manual global state cleanup.

Example

final class InvoiceTest extends TestCase
{
    use ClockSensitiveTrait;

    public function testDueDate(): void
    {
        $clock = self::mockTime('2026-01-01 10:00');
        $clock->sleep(86_400);          // one virtual day
        self::assertSame('2026-01-02', (new DatePoint())->format('Y-m-d'));
    }
}   // the original clock is restored by the #[After] hook

Anti-patterns

With dependency injection pass a MockClock to the constructor — global substitution is only needed for DI-free code.

Lifecycle

sequenceDiagram
    participant P as PHPUnit
    participant T as Test + trait
    participant H as ClockHolder
    P->>T: #[Before] saveClockBeforeTest()
    T->>H: remember current clock
    P->>T: test method
    T->>H: mockTime() sets MockClock
    P->>T: #[After] restoreClockAfterTest()
    T->>H: reset + restore saved clock

Feature comparison with competitors

Aspect🏆 CloudCastlesymfonycarbonlcobuccibesteergebnis
One-line time mocking in a test✅✅❌❌❌❌
Clock auto-restore after a test✅✅❌❌❌❌
Returns a MockClock to drive time✅✅❌❌❌❌
PHPUnit 10+ attributes instead of annotations✅❌❌❌❌❌
Total🏆 430000

← Back to the feature list


🇷🇺 Русский · 🇬🇧 English · 🇩🇪 Deutsch · 🇫🇷 Français · 🇪🇸 Español · 🇮🇹 Italiano