DateTime.Now に依存する単体テストの課題と戦略
DateTime.Now の値は動的に変化するため、現在時刻に依存するコードの単体テストは困難になることがよくあります。システム時刻を手動で変更することはお勧めできないため、効率的なソリューションが必要です。
ベストプラクティスは、 現在の時間の抽象化 を分離し、それをコンシューマーに注入することです。このようにして、基礎となるシステムに影響を与えることなく、単体テストで時間を操作できます。
もう 1 つのアプローチは、時間の抽象化を環境コンテキストとして定義することです。このアプローチには、現在時刻へのアクセスを提供し、テスト中にそれをモック オブジェクトに置き換えることを可能にする静的クラスの作成が含まれます。
次のコード スニペットは、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 中国語 Web サイトの他の関連記事を参照してください。