2016-02-27 66 views
3

我想在ASP.Net MVC 6中编写一个自定义模型绑定器的单元测试。它似乎很简单。模型联编程序有一个参数为ModelBindingContext的单个BindModelAsync方法。如何在ASP.Net MVC 6中测试模型联编程序?

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

然后我看着静态ModelBindingContext.CreateBindingContext,但它需要一堆可怕的参数。在MVC回购库中查看how some of the model binding tests是写的,似乎我不可能嘲笑ModelBindingContext.ModelType(除非我可以从Microsoft.AspNetCore.Mvc.TestCommon复制/粘贴这6个类)。

有什么简单/容易我失踪了吗?

+0

你不能写你的'BindModelAsync'方法不依赖于'ModelBinderContext',而是在一个包装它的接口上?然后可以进行单元测试。另外你的问题听起来更像是你需要集成测试,而不是单元测试,因为'ModelBindingContext'不能被轻易地模拟或测试,而不需要添加一堆其他的依赖项,这使得它成为一个集成测试(需要多个组件之间的交互) 。对于集成测试,您似乎没有太多的选择,因为它像Asp:Net Core团队一样 – Tseng

回答

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 
} 
相关问题