單元測試依賴 DateTime.Now 的挑戰與應對策略
單元測試依賴當前時間的程式碼往往比較棘手,因為 DateTime.Now 的值是動態變化的。手動更改系統時間不可取,因此需要有效的解決方案。
最佳實踐是隔離當前時間抽象化,並將其註入使用者。這樣,可以在單元測試中操控時間,而不會影響底層系統。
另一種方法是定義一個時間抽象化作為環境脈絡。這種方法涉及創建一個靜態類,該類提供對當前時間的訪問,並允許在測試期間用模擬對象替換它。
以下程式碼片段定義了一個作為環境上下文的 TimeProvider:
<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>
TimeProvider 的使用方法如下:
<code class="language-csharp">var now = TimeProvider.Current.UtcNow;</code>
在單元測試中,可以使用模擬物件取代 TimeProvider.Current:
<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>
務必記住,在每次測試後將 TimeProvider 重設為其預設狀態。這確保後續單元測試不受更改的時間抽象的影響。
以上是如何有效地對依賴 DateTime.Now 的程式碼進行單元測試?的詳細內容。更多資訊請關注PHP中文網其他相關文章!