DateTime.Now
: ベスト プラクティス単体テストでは、多くの場合、さまざまなシナリオをシミュレートするためにシステム時間を制御する必要があります。 システム クロックを直接変更するのは非現実的であり、危険です。 解決策は、依存関係の注入 と 抽象化 にあります。
重要なのは、時間ソースを抽象化し、それをコードに挿入することです。これにより、テスト中にリアルタイム プロバイダーをモックに簡単に置き換えることができます。
インターフェースを作成しましょう:
<code class="language-csharp">interface ITimeProvider { DateTime UtcNow { get; } }</code>
このインターフェースは、現在の UTC 時間を取得するためのコントラクトを定義します。 デフォルトのクラスを使用して実装します:
<code class="language-csharp">class DefaultTimeProvider : ITimeProvider { public DateTime UtcNow => DateTime.UtcNow; }</code>
次に、これを依存クラスで使用してみましょう:
<code class="language-csharp">class MyDependentClass { private readonly ITimeProvider _timeProvider; public MyDependentClass(ITimeProvider timeProvider) { _timeProvider = timeProvider; } public void MyMethod() { var currentTime = _timeProvider.UtcNow; // ... use currentTime ... } }</code>
テストでは、事前に決定された ITimeProvider
値を返すモック DateTime
を挿入し、テスト内で時間をかけて完全に制御できます。
代わりに、アンビエント コンテキストを使用することもできます。
<code class="language-csharp">public static class TimeContext { private static ITimeProvider _current = new DefaultTimeProvider(); public static ITimeProvider Current { get => _current; set => _current = value; } }</code>
これは、グローバルにアクセス可能な時刻プロバイダーを提供します。 テストでは、一時的に TimeContext.Current
をモックに設定し、副作用を避けるために各テスト後に忘れずにデフォルトに戻すことができます。
覚えておいてください: 各テストの後にアンビエント コンテキストをクリーンアップして、後続のテストやアプリケーション自体で意図しない結果が生じるのを防ぎます。 この目的には、using
ステートメントまたは finally
ブロックの使用を強くお勧めします。
以上が「DateTime.Now」に依存するコードを効果的に単体テストするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。