2009-07-03 15 views
13

私が作成したカスタムModelBinderをテストするためにいくつかの単体テストを書くのが難しいです。ユニットテストをしようとしているModelBinderは、私がhereを投稿したJsonDictionaryModelBinderです。単体テスト方法Moqを使用してカスタムModelBinderをテストしますか?

私が抱えている問題は、Moockを使ってMocking all setupを取得していることです。私は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; 
    } 
} 

答えて

7

犯人はこれです行:

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

これは、技術的には、Requestオブジェクトの2番目のSetupです。元のSetupを拭き取っていますが、これはオブジェクト階層内で "過去"になっています。私はこれがMoqのバグか望む振る舞いであるかどうかは分かりませんが、私は以前もこの問題を抱えていて、それをチェックすることに慣れていません。

上記の行を上に移動し、httpContextを経由するのではなく、直接設定することで解決できます。だから、私はまた、あなたが宣言 "のvar uは、" 使用されていないことがわかり

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

;)

+0

素晴らしい感謝! –

関連する問題