如何单元测试使用Moq的自定义ModelBinder的? [英] How to Unit Test a custom ModelBinder using Moq?

查看:127
本文介绍了如何单元测试使用Moq的自定义ModelBinder的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些困难,写一些单元测试来测试我创建一个自定义的模型绑定器。我试图单元测试ModelBinder的是,我贴<一的JsonDictionaryModelBinder href=\"http://stackoverflow.com/questions/1077481/how-do-i-pass-a-dictionary-as-a-parameter-to-an-actionresult-method-from-jquery-a/1080721#1080721\">here.

问题我有越来越嘲讽起订量使用所有的设置。我不断收到空例外,由于没有正确嘲笑HttpContextBase。我想。

有人能帮助我弄清楚什么我没有做correclty?

下面是单元测试我想写不工作的一个示例:

  [TestMethod的()]
公共无效BindModelTest()
{
    JsonDictionaryModelBinder目标=新JsonDictionaryModelBinder();    NameValueCollection中的NameValueCollection =新的NameValueCollection(){
        {第一,1},
        {二,2},
        {姓名,克里斯},
        {jsonValues​​,{ID:200,名称:克里斯'}
    };    HttpContextBase的HttpContext = MockHelper.FakeHttpContext(HttpVerbs.Post,NameValueCollection中);    ControllerContext controllerContext =
        新ControllerContext(新的RequestContext(HttpContext的,新的RouteData()),新的模拟&LT;控制方式&gt;()对象);
    predicate&LT;串GT; predicate = propertyName的= GT; (propertyName的==jsonValues​​);
    ModelBindingContext的BindingContext =新ModelBindingContext()
    {
        模型= NULL,
        ModelType = typeof运算(JsonDictionary)
        的ModelState =新ModelStateDictionary()
        PropertyFilter = predicate,
        ValueProvider =新词典&LT;字符串,ValueProviderResult&GT;(){{富,空}}
    };    //对象预计= NULL; // TODO:初始化为适当的值
    VAR实际= target.BindModel(controllerContext,BindingContext中)为JsonDictionary;    Assert.IsNotNull(实际);    Assert.AreEqual(克里斯,实际的[名称]);
    //Assert.AreEqual(expected,实际的);
    Assert.Inconclusive(验证这种测试方法的正确性。);
}

下面是上面使用的FakeHttpContext的方法:

 公共静态类MockHelper
{
    公共静态HttpContextBase FakeHttpContext(HttpVerbs动词,NameValueCollection中的NameValueCollection)
    {
        VAR的HttpContext =新的模拟&LT; HttpContextBase&GT;();        VAR要求=新的模拟&LT; Htt的prequestBase&GT;();
        request.Setup(C =&GT; c.Form).Returns(NameValueCollection中);
        request.Setup(C =&GT; c.QueryString).Returns(NameValueCollection中);        VAR响应=新的模拟&LT; Htt的presponseBase&GT;();
        VAR会话=新的模拟&LT; HttpSessionStateBase&GT;();
        VAR服务器=新的模拟&LT;&的HttpServerUtilityBase GT;();
        httpContext.Setup(C =&GT; c.Request).Returns(request.Object);        变种U = verbs.ToString()ToUpper的()。
        httpContext.Setup(C =&GT; c.Request.RequestType).Returns(
            verbs.ToString()。ToUpper的()
        );        httpContext.Setup(C =&GT; c.Response).Returns(response.Object);
        httpContext.Setup(C =&GT; c.Server).Returns(server.Object);
        httpContext.Setup(C =&GT; c.User.Identity.Name).Returns(TestClient的);
        返回httpContext.Object;
    }
}


解决方案

罪魁祸首是这一行:

  httpContext.Setup(C =&GT; c.Request.RequestType).Returns(
                verbs.ToString()。ToUpper的()
            );

这在技术上是第二个设置 Request对象上,它是消灭原始设置,甚至虽然你的对象层次去过去了。我不知道如果这是在起订量或期望的行为的错误,我以前也碰到这个并没有得到解决,以检查它。

您可以通过移动线,你在哪里设置你的要求之上,并直接设置它,而不是通过HttpContext的去解决它。因此,

  request.Setup(C =&GT; c.RequestType).Returns(verbs.ToString()ToUpper的());

我也注意到,VAR U的声明没有被使用;)

I'm having some difficulty writing some Unit Tests to test a custom ModelBinder that I created. The ModelBinder I'm trying to Unit Test is the JsonDictionaryModelBinder that I posted here.

The problem I'm having is getting the Mocking all setup using Moq. I keep getting Null Exceptions due to the HttpContextBase not being Mocked correctly. I think.

Could someone help me figure out what I'm not doing correclty?

Here's a sample of the Unit Test I'm trying to write that doesn't work:

[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.");
}

Here's the "FakeHttpContext" method used above:

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;
    }
}

解决方案

The culprit is this line:

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

This is technically a second Setup on the Request object, and it is wiping out the original Setup, even though you're going "past" it in the object hierarchy. I'm not sure if this is a bug in Moq or desired behaviour, I've run into this before as well and haven't gotten around to checking it out.

You can solve it by moving that line to where you're setting up your request above, and setting it up directly, rather than by going through the httpContext. So,

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

I also notice that the "var u" that you declare is not being used ;)

这篇关于如何单元测试使用Moq的自定义ModelBinder的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆