2016-03-30 14 views
4

DateTimeOffsetインスタンスを使用するコードを正しくテストする方法に関する情報や例がありがとうございます。私はテストが決定論的でなければならないことを知っています。DateTimeOffsetオブジェクトを使用するユニットテストクラスの正しい方法は?

したがって、どのようにアプリケーションをDateTimeOffsetクラスから隔離するのでしょうか?私は、もちろん、私のようなもの使用しなければならないなど、私のテストでは

偽DateTimeOffset.Nowを使用できるようにしたいと思います:

var myDate = new DateTimeOffset(2016, 3, 29, 12, 20, 35, 93, TimeSpan.FromHours(-3)); 

するか、私の代わりにラッパーを使用することだろうMyCustomDateTimeOffsetのようなクラスですか? 私のコードでDateTimeOffsetを使用せず、代わりにラッパーを使うべきですか? fundamentals theoremとして

答えて

7

は言う:

私たちは、間接の余分なレベルを導入することにより、任意の問題を解決することができます。

あなたは本当にラッパーを必要としません。あなたが必要とするのは避けることです。DateTimeOffset.Now/DateTimeOffset.UtcNowです。

  • あなたが依存性注入を使用している場合は、Now/UtcNowプロパティを公開IClockインタフェースを記述します。ここでは

    は、あなたがそれを扱うことができるいくつかの方法があります。

    public interface IClock 
    { 
        DateTimeOffset Now { get; } 
        DateTimeOffset UtcNow { get; } 
    } 
    
    internal class Clock : IClock 
    { 
        public DateTimeOffset Now => DateTimeOffset.Now; 
        public DateTimeOffset UtcNow => DateTimeOffset.UtcNow; 
    } 
    

    あなたのテストでは、あなたが望むようにインターフェイスをモックするだけです。

  • 静的なプロパティを引き続き使用したい場合は、静的型を記述します。たとえば、Clockとし、それを使用します。

    public static class Clock 
    { 
        internal static Func<DateTimeOffset> DateTimeOffsetProvider { get; set; } 
         =() => DateTimeOffset.Now; 
    
        public static DateTimeOffset Now => DateTimeOffsetProvider(); 
        public static DateTimeOffset UtcNow => DateTimeOffsetProvider().ToUniversalTime(); 
    } 
    

    あなたのテストでは、DateTimeOffsetProviderを代用することができます。

    public static class Clock 
    { 
        internal delegate DateTimeOffset DateTimeOffsetProviderDelegate(); 
        internal static DateTimeOffsetProviderDelegate DateTimeOffsetProvider { get; set; } 
    
        public static DateTimeOffset Now { get { return DateTimeOffsetProvider(); } } 
        public static DateTimeOffset UtcNow { get { return DateTimeOffsetProvider().ToUniversalTime(); } } 
    
        static Clock() 
        { 
         DateTimeOffsetProvider = delegate() { return DateTimeOffset.Now; }; 
        } 
    } 
    
+0

ありがとうございますが、2番目のバージョン(私がもっと好きです)は.NET 2.0プロジェクトで動作しますか? .Net 2.0のためにそれを行う他の方法があるかどうか知っていますか?ありがとう –

+0

.NET 2で使用するには、 'Func 'をカスタムデリゲートに置き換えるだけでよいので、いくつかのコードを答えに追加しました。 –

1

あなたがDateTimeOffSet.Nowの価値を知らないうように、すべてのあなたはDateTimeOffSet.Nowの値に等しいと主張することはできません。

ここでは、.NET 2バージョンがあります。 DIはなくなるの意味

  • 依存性注入
  • インターフェイスとラッパー

依存性注入(DI):

あなたはおそらく2つの方法のいずれかを使用するようにリファクタリングする必要があり方法は日付を決定し、それを渡します。

このメソッド。 。 。

public void DoSomething() 
{ 
    var now = DateTimeOffSet.Now; 
    // Do other stuff with the date 
} 

。 。 。あなたの他のオプションが(最後にあなたもこれでDIを使うだろうが)インターフェイスとラッパーを作成することである。この方法

public void DoSomething(DateTimeOffSet dtos) 
{ 
    // Do other stuff with the date 
} 

インターフェイスとラッパー

に変更します。その後、具体的なDateTimeOffSetの代わりにあなたのオブジェクトのインターフェイスを使用するので、MOQまたは他のテストライブラリを使用してインタフェースをmoqできます。 SystemWrapper(https://github.com/jozefizso/SystemWrapper)プロジェクトの例をご覧ください。

関連する問題