web-dev-qa-db-ja.com

Rhino.Mocksを使用した静的メソッドのモック

Rhino.Mocksを使用して静的メソッドをモックすることは可能ですか? Rhinoがこれをサポートしていない場合、私が同じことを達成できるようにするパターンまたは何かがありますか?

46
abhilash

Rhino.Mocksを使用して静的メソッドをモックすることは可能ですか?

いいえ、できません。

TypeMockは、CLRプロファイラーを使用して呼び出しを傍受およびリダイレクトするため、これを行うことができます。

RhinoMocks、NMock、およびMoqは、これらのライブラリーがより単純であるため、これを行うことができません。 CLRプロファイラーAPIを使用しません。これらは、プロキシを使用して仮想メンバーをインターセプトし、呼び出しをインターフェースするという点でより単純です。この単純さの欠点は、静的メソッド、静的プロパティ、シールされたクラス、非仮想インスタンスメソッドなど、特定のものをモックできないことです。

71

静的メソッド呼び出しを別のクラスの仮想インスタンスメソッドでラップし、それをモックアウトします。

22
Rytmis

TypeMockを使用してメソッド呼び出しをインターセプトできない場合、使用する推奨パターンは、テストに関心のある非仮想メソッドまたは静的メソッドに転送するプロキシを作成し、そのプロキシに期待値を設定することです。説明のために、以下のクラスを考えてください。

class TypeToTest
{
    public void Method() { }
}

interface ITypeToTest
{
    void Method();
}

class TypeToTestProxy : ITypeToTest
{
    TypeToTest m_type = new TypeToTest();

    public void Method() { m_type.Method(); }
}

このプロキシを作成することで、ITypeToTestインスタンスを渡したり設定したりする場所の代わりにTypeToTestを使用できるようになり、デフォルトの実装でTypeToTestProxyがそのまま使用されるようになります。実際の実装に転送します。次に、テストコードにモックITypeToTestを作成し、それに応じて期待値を設定できます。

これらのプロキシの作成は、非常に退屈でエラーが発生しやすく、時間がかかる可能性があることに注意してください。これに対処するために、これらのタイプを含むアセンブリを生成するライブラリとツールセットを管理します。詳細は このページ を参照してください。

17
Steve Guidi

静的なモックをサポートすることがわかっている唯一のモックフレームワークはTypeMockです。

Rytmisが示唆したように、静的なものをラップする必要があります(つまり、仮想メソッドまたはインターフェースを持つインスタンスクラス)。

4
Richard Banks

これがRhino Mocksの最大の欠点です。 Rhino Mocksがモックを行う方法を再概念化せずにこれを実装することさえ可能であることを私は知りません。

4
Vaccano

私はmoqを使用してモックを作成していますが、moQがターゲット(クラスまたはインターフェース)の新しいプロキシを作成するため、これを使用して静的メンバーをモックすることはできないと思います。したがって、継承可能なメンバー(クラスの場合は仮想、インターフェースの点ではパブリック)のみがモックできます。明らかに、静的メンバーは継承されないため、問題があります。

2
vijaysylvester