Unit Test: Isolate DateTime.Now
When doing unit testing, it is often necessary to control the current time without changing the system's clock. This creates challenges when code relies on DateTime.Now.
The best approach is to create an abstraction layer around DateTime.Now. Injecting this abstraction into the code under test allows you to simulate the current time during unit tests.
Alternative: Environmental Context
<code class="language-csharp">public abstract class TimeProvider { private static TimeProvider current = DefaultTimeProvider.Instance; public static TimeProvider Current { get { return TimeProvider.current; } set { if (value == null) { throw new ArgumentNullException("value"); } TimeProvider.current = value; } } public abstract DateTime UtcNow { get; } public static void ResetToDefault() { TimeProvider.current = DefaultTimeProvider.Instance; } }</code>
How to use it:
<code class="language-csharp">var now = TimeProvider.Current.UtcNow;</code>
In unit tests:
<code class="language-csharp">var timeMock = new Mock<TimeProvider>(); timeMock.SetupGet(tp => tp.UtcNow).Returns(new DateTime(2010, 3, 11)); TimeProvider.Current = timeMock.Object;</code>
However, be sure to clean up your test fixtures by calling TimeProvider.ResetToDefault() to avoid interfering with subsequent tests.
The above is the detailed content of How to Isolate `DateTime.Now` for Effective Unit Testing?. For more information, please follow other related articles on the PHP Chinese website!