0

次のようなコントローラークラスがあるとします。

public class ResourceController : AuthorizedController
{      
    public virtual string Resource()
    {
         //do magic
    }

    public virtual string ResourceParent()
    {
        var url = Resource();
        return url;
    }
}

}

テスト ハーネスの場合:

[Subject(typeof (ResourceController))]
public class When_I_want_the_parent_resource : WithSubject<ResourceController>
{
    private static readonly string ParentUrl = "/organizations/1";
    private static readonly string ResourceUrl = "/organizations/1/contacts/1";
    private static string _result;

    private Establish context = () =>
                                    {
                                        The<ResourceController>()
                                            .WhenToldTo(x => x.Resource())
                                            .Return(ResourceUrl);
                                    };

    private Because of = () => _result = Subject.ResourceParent();

    private It should_match_the_expected_parent_url = () =>
                             _result.ShouldEqual(ParentUrl);
}

Machine.Fakes がこのメソッドを自動モック化したために Subject.ResourceParent() が null を返すため、この単体テストは失敗します。一時的な回避策として、コードをテストできるように、ResourceParent から virtual キーワードを削除しました。Machine.Fakes にオーバーライドしないように指示するには、実際の解決策が必要だと思いますResourceParent()

4

3 に答える 3

3

実際には、これに対する Machine.Fakes の「実際の」ソリューションはありません。フィクスチャの設計を再考する必要があると私は主張します。

まず第一に、Tim がすでに指摘したように、サブジェクト自体でメソッドを偽造すべきではありません。代わりに、コントローラーの依存関係を偽造し、コントローラーを仕様どおりに使用する必要があります。「The」メソッドの使用目的は、仕様の下でサブジェクトの依存関係にアクセスすることですが、仕様で試みるのは、サブジェクト自体にアクセスすることです。私はそれが物事がうまくいかないところだと思います。<ResourceController> とサブジェクトは、実際には別個のインスタンスです。そのため、設定した相互作用は発生しません。

コードでこれを修正するためのいくつかのオプション:

  • 「The」を介してスタブできるコードに新しい依存関係を導入します
  • 最初のメソッドが重いと思われる場合は、仮想メソッドをコントローラーの Func<string> 依存関係に置き換え、"Configure" メソッドを使用して仕様固有の仕様を挿入することもできます。

HTH、

ビョルン

于 2012-03-25T12:59:15.403 に答える
2

コントローラーをテストしている場合、おそらくそのコントローラーのモックやフェイクを作成するべきではありません。それ以外の場合は、モックをテストしているだけであり、テストには実際には有効性がありません。

コントローラーの依存関係をモックまたは偽造します。実際のコントローラーをテストします。

于 2012-03-23T23:56:14.463 に答える
0

最終的に、このテストを Machine.Fakes から取り出して、通常の単体テストに入れました。次に、Moq を直接使用してHttpRequestBase必要なデータをシードするように構成し、コントローラー クラスを手動で作成してメソッドを呼び出しました。

于 2012-03-29T12:54:46.747 に答える