単体テストを希望する場合は静的なクラスを使わないでください。ただし、静的なクラスを選択する必要がない場合は、単体テストのための動作を制御できます(厳密に言うとあざける!)DateTimeクラスは非常に便利なDateTime.Now静的メソッドが含まれていますが、ユニットテストので、「今」は常に変化している総痛みです。たとえば、
。これをラウンドするために、私はそれをラップする静的クラスを作成しました。
public static class SystemTime
{
private static DateTime _date;
public static DateTime Now => _date != DateTime.MinValue ? _date : DateTime.Now;
public static DateTime Today => _date == DateTime.MinValue ? DateTime.Today : _date.Date;
[Conditional("DEBUG")]
public static void Set(DateTime date)
{
_date = date;
}
public static void Reset()
{
_date = DateTime.MinValue;
}
}
これは、単体テスト用に操作できる静的クラスの例です。テストクラスのセットアップメソッドでは、SystemTimeを "Set"して常に必要な値を返すようにして、現在の時刻をテスト可能にするテストコードをテスト可能にすることができます。独自の静的クラスの重要な部分は、静的クラスを「テスト」状態でセットアップできるため、ユニットテストではある方法で動作しますが、リリースコードでは動作が異なります。
これを行うには、コードの機能を変更するために設定できるプロパティまたはメソッドを追加する必要があります。しかし、問題はありますが、それは静的なので一度設定すると設定されたままです。このラウンドを取得するには、クラスを元の状態に戻すことを絶対に忘れないでください。このコードをテストクラスのティアダウンメソッドに入れて、リセットするのを忘れることはありません。もう1つの問題は、導入するこれらのメソッドとプロパティが、非テストコードによって呼び出される可能性があるということです。これを避けるには、 "DEBUG"属性を設定するか、#if DEBUGブロックにテスト専用メソッド/プロパティをラップします。これは、開発中に誤ってプロパティを設定することを止めるものではありませんが、リリースビルドを壊して問題にフラグを立てます。このアプローチは慎重に使用してください!
EDIT:
私は非静的作ることができなかった静的なクラスを持っていたクラスが、私はこれを実装する静的クラスのラッパーを作成し、インターフェイスを作成することになり、上記簡単な例以上だった場合このインタフェースも実装されているモッククラスを使用します。私はコンストラクタ(私が好む)でクラスに渡すか、プロパティとして設定します。テストではモックバージョンを渡しますが、実際の実装ではラップバージョンで渡します。
MyStaticClassをいくつかのインターフェイスを実装する非静的クラスにラップすると、完了です。 – raven
Gracias Roberto ;-)私はそれを –