如何对自定义ModelBinder进行单元测试?

这是代码。

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

这是测试脚本。
[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; }
}

问题?在MagicBinder中,bindingContext.Model为null。如果我尝试用
bindingContext.Model =新的Foo()。我得到一个异常(exception),说它已被弃用,我应该设置ModelMetadata。

那么如何构造ModelMetadata?它甚至不能被 mock 。

最佳答案

注意:此答案适用于.NET Framework上的ASP.NET,可能已过时。
尝试这样:

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

关于asp.net-mvc-3 - 如何使用ModelMetadata对Modelbinder进行单元测试,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5038430/

10-13 00:24