FakeTimeProvider from Microsoft.Extensions.TimeProvider.Testing is only the starting point for time-based testing in .NET. The real challenges involve understanding the difference between SetUtcNow (no callbacks) and Advance (fires callbacks), synchronizing async timer callbacks using TaskCompletionSource, correctly ordering awaits before advancing time with PeriodicTimer, using the CancellationTokenSource overload that accepts a TimeProvider to avoid flaky tests, and managing DI lifetime contamination when sharing a WebApplicationFactory across tests. The post also covers BackgroundService integration test patterns and lists scenarios FakeTimeProvider cannot handle, such as DST transitions and Stopwatch precision.
Table of contents
The Easy Half: A Clock You ControlAdvance vs SetUtcNow: The Distinction That MattersThe Hard Half: Asynchronous CallbacksPattern: PeriodicTimer Under FakeTimeProviderPattern: CancelAfter With Controlled TimePattern: BackgroundService With a ScheduleThe DI Lifetime TrapWhat You Cannot Test This WayWhen the Pattern Is Wrong14.8K Impressions