2016-11-19 9 views
0

注:質問は下部にあります。IOCを使用しない依存性注入 - 実動コードで間違った使用を避けるにはどうすればよいですか?

私はレガシープロジェクト(ユニットテストの対象範囲は0)で作業しており、システム全体をリファクタリングしてIOCを使用することはできません。今のところ、私たちはパブリックセッター(私はこれが悪いことを知っている)によって擬似/擬似オブジェクトを注入しようとしています。

これは、我々は上記の設計は私にユニットテストの時間を完全に制御を提供したいくつかのシングルトン

public class SingletonContainer 
{ 
    private static IClock clock = new RealClock(); 

    private static SingletonContainer container; 
    public static SingletonContainer Instance 
    { 
     /* some singleton implementation*/ 
    } 

    public IClock Clock { get; set;} 
} 

// IClock has 2 implementations : RealClock and ManualClock 
public interface IClock 
{ 
    DateTime Now(); // In real clock will only return DateTime.Now 
         // In Manual clock will always return the time from SetTime() 
    void SetTime(DateTime newTime); // In real clock will threw exception. 
} 

にモックを注入しようとする例の一つです。 しかし、開発者がテストコードではなく誤ってSetTime()を呼び出すことは望ましくありません。

ジョンスキートはそれが

if (assembly.FullName.ToLowerInvariant().StartsWith("nunit.framework")) 

によって行うことができる。しかしそのアイデアは、デザインレビュー時にシャットダウンしまったことを示唆しています。テクノロジーリーダーは、代わりにこの問題を解決するためにクラス設計を使用したいと考えています。

質問:ManualClockを非表示にしたり、不快なハックを実装せずにSetTime()メソッドを非表示にする方法はありますか?

答えて

1

私はちょうどIClock.SetTime宣言を取り除き、メソッドをManualClockクラスでのみ定義します。つまり、あなたが持っている可能性のあるテストからManualClassインスタンスにアクセスできる場合です。

IClockにSetTimeを設定すると、デザインの匂いのように見えます。 Specifically I think it violates LSP (Liskov substitution principle)

+0

ああ、あなたは私のオリジナルデザインを思い出させます。 realclockは、何もしなかったsetTimeメソッドを決して持つべきではありません。最初に例外をスローします。 IClockは、NowやTodayのようなデータ型をラップアップするラッパークラスでなければなりません。 ManualClock(これはnunitテストプロジェクトにのみ存在します)ではなく、SetTimeメソッドが必要です。問題を解決するためのよりクリーンな方法のように見える – cscmh99

関連する問題