6

ビジネス プロセスが現在時刻に依存するシステムを構築する場合[1]、コードで使用することはできませんDateTime.Now。たとえば、将来の月末または年末のシナリオでテストを処理する必要があるためです。オペレーティング システムの時刻を変更することは、一般に、SSL 証明書を使用する場合のオプションではありません。これは、分散システムで修正を行うのが複雑であるためです。

1 つのオプションは、現在の時刻を返すすべてのシステムからアクセスできるシングルトン サービスを作成することです。本番環境では返される可能性がDateTime.Nowあり、テストでは、月末のシナリオで 2 月 28 日のようなゲーム時間を返す可能性があります。

しかし、これを行うより良い方法はありますか? パフォーマンスの向上につながるため、よりデータベース指向のアプローチが好きですか? それとも、分散キャッシュを入れますか? このためのよく知られたデザインパターンはありますか?

[1]典型的な例: 保険システム、基幹銀行システムなどによって実装されるビジネス プロセス

4

5 に答える 5

4

この問題に対処する 1 つの方法は、クロック インターフェイスを使用することです。

public interface IClock {
  DateTime Now { get; }
}

の代わりに、コード全体でこのインターフェイスを使用しますDateTime.Now。本番環境では、正規の実装 (または UTC バリアント) を使用します。

public class SystemClock implements IClock {
  public DateTime Now { get { return DateTime.Now; } }
}

たとえば、コンストラクターまたはセッターを介して他の実装を注入するSystemClock必要があり、それを許可するすべてのクラスでデフォルトとして使用できます。IClock

テストでは、テスト実装を作成するか、モッキング フレームワークでそれをモックできます。

于 2013-10-15T11:01:01.297 に答える
2

あなたが話していることを達成するために、 Microsoft Fakesを使用することを検討できます。

このわずかに変更された例を参照してください。

[TestMethod]
public void TestCurrentYear()
{
    int fixedYear = 2000;

    // Shims can be used only in a ShimsContext:
    using (ShimsContext.Create())
    {
        // Arrange:
        // Shim DateTime.Now to return a fixed date:
        System.Fakes.ShimDateTime.NowGet =  
        () =>
        { return new DateTime(fixedYear, 1, 1); };

        // Act:
        int year = DateTime.Now.Year;

        // Assert: 
        Assert.AreEqual(fixedYear, year);
    }
}

ここでの利点は、テスト可能にするために DateTime を使用するコードを変更する必要がないことです。

于 2013-10-15T11:02:08.300 に答える