Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test modelbinder with ModelMetadata

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.

like image 570
Sleeper Smith Avatar asked Feb 18 '11 06:02

Sleeper Smith


1 Answers

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: } 
like image 111
Darin Dimitrov Avatar answered Sep 20 '22 17:09

Darin Dimitrov