私はモックオブジェクトを初めて使用しますが、モックを作成するには、クラスにインターフェイスを実装させる必要があることを理解しています。
私が抱えている問題は、データアクセス層に静的メソッドが必要なのに、インターフェイスに静的メソッドを配置できないことです。
これを回避する最善の方法は何ですか?インスタンスメソッドを使用する必要がありますか(これは間違っているようです)、それとも別の解決策がありますか?
私はモックオブジェクトを初めて使用しますが、モックを作成するには、クラスにインターフェイスを実装させる必要があることを理解しています。
私が抱えている問題は、データアクセス層に静的メソッドが必要なのに、インターフェイスに静的メソッドを配置できないことです。
これを回避する最善の方法は何ですか?インスタンスメソッドを使用する必要がありますか(これは間違っているようです)、それとも別の解決策がありますか?
はい、インスタンス メソッドを使用します。静的メソッドは基本的に、「この機能を実現する方法は 1 つあります。それはポリモーフィックではありません」ということです。モッキングはポリモーフィズムに依存しています。
さて、あなたの静的メソッドがあなたが使用している実装を論理的に気にしない場合、それらはインターフェースをパラメーターとして取ることができるか、または状態とまったく対話せずに動作する可能性があります-しかし、それ以外の場合はインスタンスを使用する必要があります(おそらくすべてを結び付ける依存性注入)。
これを行う方法に関するいくつかの素晴らしい例を含むブログをグーグルで見つけました:
クラスをインスタンス クラスにリファクタリングし、インターフェイスを実装します。
あなたはこれをしたくないとすでに述べました。
静的クラス メンバーのデリゲートでラッパー インスタンス クラスを使用する
これを行うと、デリゲートを介して静的インターフェイスをシミュレートできます。
静的クラスを呼び出す保護されたメンバーでラッパー インスタンス クラスを使用する
これは、継承して拡張できるため、おそらくリファクタリングなしでモック/管理するのが最も簡単です。
メソッド オブジェクト パターンを使用します。これの静的インスタンスを用意し、静的メソッドで呼び出します。モック フレームワークによっては、テスト用にサブクラス化できるはずです。
つまり、静的メソッドを持つクラスには次のものがあります。
private static final MethodObject methodObject = new MethodObject();
public static void doSomething(){
methodObject.doSomething();
}
メソッド オブジェクトは非常に単純で、簡単にテストできます。
public class MethodObject {
public void doSomething() {
// do your thang
}
}
深すぎる開始点でテストしようとしている可能性があります。すべてのメソッドを個別にテストするためにテストを作成する必要はありません。プライベート メソッドと静的メソッドは、プライベート メソッドと静的メソッドを順番に呼び出すパブリック メソッドを呼び出してテストする必要があります。
したがって、コードが次のようになっているとしましょう。
public object GetData()
{
object obj1 = GetDataFromWherever();
object obj2 = TransformData(obj1);
return obj2;
}
private static object TransformData(object obj)
{
//Do whatever
}
TransformData メソッドに対するテストを作成する必要はありません (できません)。代わりに、TransformData で行われた作業をテストする GetData メソッドのテストを記述します。
可能な場合はインスタンス メソッドを使用します。
インスタンス メソッドが使用できない場所では、public static Func[T, U] (モック関数の代わりに使用できる静的関数参照) を使用します。
簡単な解決策は、セッターを介して静的クラスの実装を変更できるようにすることです。
class ClassWithStatics {
private IClassWithStaticsImpl implementation = new DefaultClassWithStaticsImpl();
// Should only be invoked for testing purposes
public static void overrideImplementation(IClassWithStaticsImpl implementation) {
ClassWithStatics.implementation = implementation;
}
public static Foo someMethod() {
return implementation.someMethod();
}
}
したがって、テストのセットアップでは、overrideImplementation
モック インターフェイスを使用して呼び出します。利点は、静的クラスのクライアントを変更する必要がないことです。欠点は、静的クラスのメソッドとその実装を繰り返す必要があるため、コードが少し重複する可能性があることです。ただし、静的メソッドは、基本機能を提供する軽量インターフェースを使用できる場合があります。