【问题标题】:How to test model binder in ASP.Net MVC 6?如何在 ASP.Net MVC 6 中测试模型绑定器?
【发布时间】:2017-06-03 01:08:42
【问题描述】:

我正在尝试为 ASP.Net MVC 6 中的自定义模型绑定器编写单元测试。看起来很简单。模型绑定器有一个 BindModelAsync 方法,它采用 ModelBindingContext 参数。

在我的单元测试中,我试图弄清楚如何伪造ModelBindingContext。起初,我认为我可以使用默认构造函数并在我需要的对象上设置属性。这适用于除不可设置的ModelType 之外的所有属性。

然后我查看了静态的ModelBindingContext.CreateBindingContext,但它需要一堆看起来很吓人的参数。查看 MVC 存储库中编写的how some of the model binding tests,我似乎无法模拟ModelBindingContext.ModelType(除非我可能从Microsoft.AspNetCore.Mvc.TestCommon 复制/粘贴这6 个类)。

我缺少什么简单/容易的东西吗?

【问题讨论】:

  • 难道你不能编写你的BindModelAsync 方法不依赖于ModelBinderContext,而是依赖于一个环绕它的接口吗?然后可以进行单元测试。此外,您的问题听起来更像是您需要集成测试,而不是单元测试,因为 ModelBindingContext 在不添加一堆其他依赖项的情况下无法轻松模拟或测试,这使其成为集成测试(需要多个组件之间的交互) .对于集成测试,您似乎没有太多选择,就像 Asp:Net Core 团队那样

标签: asp.net-core asp.net-core-mvc


【解决方案1】:

我已经成功地将它用于一些简单的表单和查询字符串值。 AspNetCore.Mvc v1.1.3

private static DefaultModelBindingContext GetBindingContext(IValueProvider valueProvider, Type modelType)
{
    var metadataProvider = new EmptyModelMetadataProvider();
    var bindingContext = new DefaultModelBindingContext
    {
        ModelMetadata = metadataProvider.GetMetadataForType(modelType),
        ModelName = modelType.Name,
        ModelState = new ModelStateDictionary(),
        ValueProvider = valueProvider,
    };
    return bindingContext;
}

使用查询字符串提供程序

[TestMethod]
public async Task QueryStringValueProviderTest()
{
    var binder = new MyModelBinder();

    var queryCollection = new QueryCollection(
        new Dictionary<string, StringValues>()
        {
            { "param1", new StringValues("1") },
            { "param2", new StringValues("2") },
        });
    var vp = new QueryStringValueProvider(BindingSource.Query, queryCollection, CultureInfo.CurrentCulture);

    var context = GetBindingContext(vp, typeof(MyModel));

    await binder.BindModelAsync(context);

    var resultModel = context.Result.Model as MyModel;

    //TODO Asserts
}

使用表单集合提供程序

[TestMethod]
public async Task FormValueProviderTest()
{
    var binder = new MyModelBinder();

    var formCollection = new FormCollection(
        new Dictionary<string, StringValues>()
        {
            { "param1", new StringValues("1") },
            { "param2", new StringValues("2") }
        });
    var vp = new FormValueProvider(BindingSource.Form, formCollection, CultureInfo.CurrentCulture);

    var context = GetBindingContext(vp, typeof(MyModel));

    await binder.BindModelAsync(context);

    var resultModel = context.Result.Model as MyModel;

    //TODO asserts
}

【讨论】:

  • 太棒了。查询字符串示例正是我所需要的。你会认为微软会有一些关于单元测试模型绑定的很好的文档,因为它被广泛使用......
  • 作为记录,这也适用于 ASP.NET Core MVC
猜你喜欢
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多