How do I unit test a custom ModelBinder?
Here's the code.
public class MagicBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { var boundModelObject = base.BindModel(controllerContext, bindingContext); var properties = bindingContext.ModelType.GetProperties().Where(a => a.CanWrite); foreach (var propertyInfo in properties) { object outValue = null; bindingContext.TryGetValue(propertyInfo.Name, propertyInfo.DeclaringType, out outValue); propertyInfo.SetValue(boundModelObject, outValue, null); } return boundModelObject; } }
And here is the test script.
[TestMethod] public void TestFooBinding() { var dict = new ValueProviderDictionary(null) { {"Number", new ValueProviderResult("2", "2", null)}, {"Test", new ValueProviderResult("12", "12", null)}, }; var bindingContext = new ModelBindingContext() { ModelName = "foo", ValueProvider = dict}; var target = new MagicBinder(); Foo result = (Foo)target.BindModel(null, bindingContext); } public class Foo { public int Number { get; set; } public int Test { get; set; } }
Problem? In the MagicBinder, bindingContext.Model is null. If I try set it with bindingContext.Model = new Foo(). I get an exception saying it is deprecated, and I should set the ModelMetadata.
So how do I construct a ModelMetadata? It can't even be mocked.
NOTE: This answer is for ASP.NET on .NET Framework and might be outdated.
Try like this:
[TestMethod] public void TestFooBinding() { // arrange var formCollection = new NameValueCollection { { "Number", "2" }, { "Test", "12" }, }; var valueProvider = new NameValueCollectionValueProvider(formCollection, null); var metadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(Foo)); var bindingContext = new ModelBindingContext { ModelName = "", ValueProvider = valueProvider, ModelMetadata = metadata }; var controllerContext = new ControllerContext(); var sut = new MagicBinder(); // act Foo actual = (Foo)sut.BindModel(controllerContext, bindingContext); // assert // TODO: }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With