Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
521 views
Welcome To Ask or Share your Answers For Others

1 Answer

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:
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...