スタブに関する最近の質問では、多くの回答がスタブを実装するための C# インターフェイスまたはデリゲートを提案していましたが、1 つの回答は、条件付きコンパイルを使用して、運用コードで静的バインディングを保持することを提案していました。この回答は、読んだ時点で -2 に変更されたため、少なくとも 2 人がこれは間違った回答だと本当に思っていました。おそらく、DEBUG の誤用が原因であるか、より広範な検証の代わりに固定値を使用している可能性があります。しかし、私は不思議に思わずにはいられません:
条件付きコンパイルの使用は、単体テスト スタブを実装するための不適切な手法ですか? 時々?いつも?
ありがとう。
編集-追加: 実験として例を追加したいと思います:
class Foo {
public Foo() { .. }
private DateTime Now {
get {
#if UNITTEST_Foo
return Stub_DateTime.Now;
#else
return DateTime.Now;
#endif
}
}
// .. rest of Foo members
}
との比較
interface IDateTimeStrategy {
DateTime Now { get; }
}
class ProductionDateTimeStrategy : IDateTimeStrategy {
public DateTime Now { get { return DateTime.Now; } }
}
class Foo {
public Foo() : Foo(new ProductionDateTimeStrategy()) {}
public Foo(IDateTimeStrategy s) { datetimeStrategy = s; .. }
private IDateTime_Strategy datetimeStrategy;
private DateTime Now { get { return datetimeStrategy.Now; } }
}
これにより、「DateTime.Now」への発信依存関係を C# インターフェイス経由でスタブ化できます。ただし、静的で十分な動的ディスパッチ呼び出しを追加し、オブジェクトは製品バージョンでも大きくなり、Foo のコンストラクターに新しい失敗パスを追加しました (割り当てが失敗する可能性があります)。
私はここで何も心配していませんか?これまでのフィードバックに感謝します!