13

作成したカスタムModelBinderをテストするためのユニットテストを作成するのに問題があります。私がユニットテストしようとしているModelBinderは、ここに投稿したJsonDictionaryModelBinderです。

私が抱えている問題は、Moqを使用してすべてのモックを設定することです。HttpContextBaseが正しくモックされていないため、Null例外が発生し続けます。おもう。

誰かが私が正しくやっていないことを理解するのを手伝ってもらえますか?

これが私が書き込もうとしているユニットテストのサンプルですが、機能しません:

[TestMethod()]
public void BindModelTest()
{
    JsonDictionaryModelBinder target = new JsonDictionaryModelBinder();

    NameValueCollection nameValueCollection = new NameValueCollection() {
        {"First", "1"},
        {"Second", "2"},
        {"Name", "Chris"},
        {"jsonValues", "{id: 200, name: 'Chris'}"}
    };

    HttpContextBase httpContext = MockHelper.FakeHttpContext(HttpVerbs.Post, nameValueCollection);

    ControllerContext controllerContext =
        new ControllerContext(new RequestContext(httpContext, new RouteData()), new Mock<Controller>().Object);


    Predicate<string> predicate = propertyName => (propertyName == "jsonValues");
    ModelBindingContext bindingContext = new ModelBindingContext()
    {
        Model = null,
        ModelType = typeof(JsonDictionary),
        ModelState = new ModelStateDictionary(),
        PropertyFilter = predicate,
        ValueProvider = new Dictionary<string, ValueProviderResult>() { { "foo", null } }
    };

    //object expected = null; // TODO: Initialize to an appropriate value
    var actual = target.BindModel(controllerContext, bindingContext) as JsonDictionary;

    Assert.IsNotNull(actual);

    Assert.AreEqual("Chris", actual["name"]);
    //Assert.AreEqual(expected, actual);
    Assert.Inconclusive("Verify the correctness of this test method.");
}

上記で使用した「FakeHttpContext」メソッドは次のとおりです。

public static class MockHelper
{
    public static HttpContextBase FakeHttpContext(HttpVerbs verbs, NameValueCollection nameValueCollection)
    {
        var httpContext = new Mock<HttpContextBase>();

        var request = new Mock<HttpRequestBase>();
        request.Setup(c => c.Form).Returns(nameValueCollection);
        request.Setup(c => c.QueryString).Returns(nameValueCollection);

        var response = new Mock<HttpResponseBase>();
        var session = new Mock<HttpSessionStateBase>();
        var server = new Mock<HttpServerUtilityBase>();
        httpContext.Setup(c => c.Request).Returns(request.Object);

        var u = verbs.ToString().ToUpper();
        httpContext.Setup(c => c.Request.RequestType).Returns(
            verbs.ToString().ToUpper()
        );

        httpContext.Setup(c => c.Response).Returns(response.Object);
        httpContext.Setup(c => c.Server).Returns(server.Object);
        httpContext.Setup(c => c.User.Identity.Name).Returns("testclient");
        return httpContext.Object;
    }
}
4

1 に答える 1

7

犯人はこの行です:

httpContext.Setup(c => c.Request.RequestType).Returns(
                verbs.ToString().ToUpper()
            );

これは技術的SetupにはRequestオブジェクトの2番目でSetupあり、オブジェクト階層で「過去」に行ったとしても、元のオブジェクトを消去します。これがMoqのバグなのか、それとも望ましい動作なのかはわかりません。以前にもこれに遭遇したことがあり、チェックアウトすることはできませんでした。

その行を上記のリクエストを設定している場所に移動し、httpContextを経由するのではなく、直接設定することで解決できます。それで、

request.Setup(c => c.RequestType).Returns(verbs.ToString().ToUpper());

また、あなたが宣言した「varu」が使用されていないことにも気づきました;)

于 2009-07-04T02:41:28.140 に答える