Time system
ITimeSystem wraps everything in the BCL that depends on the wall clock or makes a thread wait. Replace it with a MockTimeSystem in tests and you can fast-forward time without sleeping.
What it covers
| Sub-property | Wraps |
|---|---|
DateTime | DateTime.Now, DateTime.UtcNow, DateTime.Today (plus MinValue, MaxValue, UnixEpoch) |
DateTimeOffset | DateTimeOffset.Now, DateTimeOffset.UtcNow (plus MinValue, MaxValue, UnixEpoch) |
Stopwatch | System.Diagnostics.Stopwatch |
Task | Task.Delay |
Thread | Thread.Sleep |
PeriodicTimer | System.Threading.PeriodicTimer (.NET 8 or later) |
Timer | System.Threading.Timer |
TimeZoneInfo | System.TimeZoneInfo (Local, Utc, FindSystemTimeZoneById, GetSystemTimeZones) |
Implementations
| Type | Package | Use it for |
|---|---|---|
RealTimeSystem | Testably.Abstractions | Production |
MockTimeSystem | Testably.Abstractions.Testing | Unit tests |
ITimeSystem timeSystem = new MockTimeSystem();
// any Thread.Sleep / Task.Delay / Stopwatch / Timer call goes through this instance
timeSystem.Thread.Sleep(TimeSpan.FromMinutes(5));
DateTime now = timeSystem.DateTime.Now; // advanced by 5 minutes
In this section
Configuring time
Choose the start time and the local time zone of the MockTimeSystem, plug in a custom time provider, or use it as a .NET TimeProvider.
Auto-advance
How MockTimeSystem moves its clock when the code under test waits, and how to drive the clock yourself.
Stopwatch
Measure simulated elapsed time with the mocked Stopwatch, independent of changes to the wall clock.
Timer
Wait for a mocked System.Threading.Timer to fire a given number of times instead of sleeping.
PeriodicTimer
Test loops built on PeriodicTimer without waiting for real time to pass.
Notifications
Observe and wait for sleeps, delays, clock reads and timer ticks of the code under test.
Thread-aware time provider
Give each async context its own simulated clock with a custom ITimeProvider.