1 か月前に「Art of Unit Testing」という本を読み終え、今日ようやく Rhino Mocks を使用して、デバイス (UDP) にメッセージを送受信し、データベースからデータを保存/ロードするサービスの単体テストを開始する時間がありました。
もちろん、データベースと UDP 通信を分離したいと考えています。
たとえば、データベースアクセスの場合、静的メソッドを持つクラスがいくつかあります。それらを呼び出しましょう。
- エリアADBアクセス
- エリアBDBアクセス
- エリアCDBアクセス
これらのクラスには、データベース アクセスを実行する静的メソッドがありました。
それらをスタブできるようにするために、メソッドを public virtual にしました。
次に、コード上のこれらのクラスのインスタンスを置き換えることができるように、コードのリファクタリングを開始しました。
さまざまなことを試した後、物事をとても簡単にするように見えるファクトリークラスにたどり着きました。
public class ObjectFactory
{
private static Dictionary<Type, object> Instances = new Dictionary<Type, object>();
public static T GetInstance<T>() where T : new()
{
if(Instances.ContainsKey(typeof(T)))
return (T)Instances[typeof(T)];
return new T();
}
public static void SetInstance<T>(object obj)
{
Instances[typeof(T)] = obj;
}
}
次に、コードで使用できます
private AreaADBAccess DBAccess = ObjectFactory.GetInstance<AreaADBAccess>();
そして、テストメソッドで私は次のようなことをします
AreaADBAccess dbAccess = mocks.Stub<AreaADBAccess>();
using (mocks.Record())
{
...
}
ObjectFactory.SetInstance<AreaADBAccess>(dbAccess);
//Invoke the test method
...
これは最初の解決策であり、より良い方法で実行できることを認識しています。
コメントして、ベストプラクティスを教えていただけますか?
また、メソッドを仮想として定義するのではなく、インターフェイスが必要な理由を説明してもらえますか? メソッドヘッダーを 2 か所繰り返すのは無駄に思えます。
ありがとう!