Reputation: 2456
I'm trying to write a unit test for a custom model binder in ASP.Net MVC 6. It seems simple enough. The model binder has a single BindModelAsync
method which takes a ModelBindingContext
parameter.
In my unit test, I'm trying to figure out how to fake the ModelBindingContext
. At first, I thought I could use the default constructor and set the properties on the object that I need. This works for all of the properties except ModelType
which is not settable.
I then looked at the static ModelBindingContext.CreateBindingContext
but it takes a bunch of scary looking parameters. Looking at how some of the model binding tests within the MVC repo are written, it seems like it is not possible for me to mock the ModelBindingContext.ModelType
(unless maybe I copy/paste those 6 classes from Microsoft.AspNetCore.Mvc.TestCommon).
Is there something simple/easy I am missing?
Upvotes: 8
Views: 2882
Reputation: 12410
I've had some success in getting it working for some simple form and query string values. 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;
}
Using a query string provider
[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
}
Using a form collection provider
[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
}
Upvotes: 8