如何在ASP.Net MVC 6中测试模型绑定器?

时间:2016-02-27 19:28:06

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

我试图在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个类)。< / p>

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

1 个答案:

答案 0 :(得分:8)

我在使用一些简单的表单和查询字符串值方面取得了一些成功。 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
}