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

Cha*_*had 7 asp.net-core-mvc asp.net-core

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

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

然后我查看了静态,ModelBindingContext.CreateBindingContext但它需要一堆可怕的参数.看看MVC repo中的一些模型绑定测试是如何编写的,似乎我不可能模拟ModelBindingContext.ModelType(除非我可以从Microsoft.AspNetCore.Mvc.TestCommon复制/粘贴这6个类).

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

Sho*_*hoe 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;
}
Run Code Online (Sandbox Code Playgroud)

使用查询字符串提供程序

[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
}
Run Code Online (Sandbox Code Playgroud)

使用表单集合提供程序

[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
}
Run Code Online (Sandbox Code Playgroud)