Skip to content

Do your unit tests depend on the system clock?

Testing code that uses new DateTime('now') or time() is painful. You end up mocking native functions, or accepting fragile tests that fail at midnight.

Direct dependency on a concrete implementation causes the same kind of problems for the logger, the cache, or the ID generator...

Phexium structures every infrastructure service as a plugin: an interface (Port) and implementations (Adapters). Business code depends on ClockInterface, never on SystemClock.

In production, the container injects SystemClock. In tests, it injects FrozenClock:

$clock = new FrozenClock('2024-03-01T10:00:00+00:00');
$loan = new Loan($clock->now(), durationDays: 14);
$clock->advance(days: 15);
expect($loan->isOverdue($clock->now()))->toBeTrue();

No mocks needed, no monkey-patching. The test controls time directly.

Cache, session, and password hashing work on exactly the same principle. Every plugin provides a test adapter.