1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.TestUtil;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Mvc.Test
{
public class ModelBinderDictionaryTest
{
[Fact]
public void DefaultBinderIsInstanceOfDefaultModelBinder()
{
// Arrange
ModelBinderDictionary binders = new ModelBinderDictionary();
// Act
IModelBinder defaultBinder = binders.DefaultBinder;
// Assert
Assert.IsType<DefaultModelBinder>(defaultBinder);
}
[Fact]
public void DefaultBinderProperty()
{
// Arrange
ModelBinderDictionary binders = new ModelBinderDictionary();
IModelBinder binder = new Mock<IModelBinder>().Object;
// Act & assert
MemberHelper.TestPropertyWithDefaultInstance(binders, "DefaultBinder", binder);
}
[Fact]
public void DictionaryInterface()
{
// Arrange
DictionaryHelper<Type, IModelBinder> helper = new DictionaryHelper<Type, IModelBinder>()
{
Creator = () => new ModelBinderDictionary(),
SampleKeys = new Type[] { typeof(object), typeof(string), typeof(int), typeof(long), typeof(long) },
SampleValues = new IModelBinder[] { new DefaultModelBinder(), new DefaultModelBinder(), new DefaultModelBinder(), new DefaultModelBinder(), new DefaultModelBinder() },
ThrowOnKeyNotFound = false
};
// Act & assert
helper.Execute();
}
[Fact]
public void GetBinderConsultsProviders()
{
// Arrange
Type modelType = typeof(string);
IModelBinder expectedBinderFromProvider = new Mock<IModelBinder>().Object;
Mock<IModelBinderProvider> locatedProvider = new Mock<IModelBinderProvider>();
locatedProvider.Setup(p => p.GetBinder(modelType))
.Returns(expectedBinderFromProvider);
Mock<IModelBinderProvider> secondProvider = new Mock<IModelBinderProvider>();
ModelBinderProviderCollection providers = new ModelBinderProviderCollection(new IModelBinderProvider[] { locatedProvider.Object, secondProvider.Object });
ModelBinderDictionary binders = new ModelBinderDictionary(providers);
// Act
IModelBinder returnedBinder = binders.GetBinder(modelType);
// Assert
Assert.Same(expectedBinderFromProvider, returnedBinder);
}
[Fact]
public void GetBinderDoesNotReturnDefaultBinderIfAskedNotTo()
{
// Proper order of precedence:
// 1. Binder registered in the global table
// 2. Binder attribute defined on the type
// 3. <null>
// Arrange
IModelBinder registeredFirstBinder = new Mock<IModelBinder>().Object;
ModelBinderDictionary binders = new ModelBinderDictionary()
{
{ typeof(MyFirstConvertibleType), registeredFirstBinder }
};
// Act
IModelBinder binder1 = binders.GetBinder(typeof(MyFirstConvertibleType), false /* fallbackToDefault */);
IModelBinder binder2 = binders.GetBinder(typeof(MySecondConvertibleType), false /* fallbackToDefault */);
IModelBinder binder3 = binders.GetBinder(typeof(object), false /* fallbackToDefault */);
// Assert
Assert.Same(registeredFirstBinder, binder1);
Assert.IsType<MySecondBinder>(binder2);
Assert.Null(binder3);
}
[Fact]
public void GetBinderResolvesBindersWithCorrectPrecedence()
{
// Proper order of precedence:
// 1. Binder registered in the global table
// 2. Binder attribute defined on the type
// 3. Default binder
// Arrange
IModelBinder registeredFirstBinder = new Mock<IModelBinder>().Object;
ModelBinderDictionary binders = new ModelBinderDictionary()
{
{ typeof(MyFirstConvertibleType), registeredFirstBinder }
};
IModelBinder defaultBinder = new Mock<IModelBinder>().Object;
binders.DefaultBinder = defaultBinder;
// Act
IModelBinder binder1 = binders.GetBinder(typeof(MyFirstConvertibleType));
IModelBinder binder2 = binders.GetBinder(typeof(MySecondConvertibleType));
IModelBinder binder3 = binders.GetBinder(typeof(object));
// Assert
Assert.Same(registeredFirstBinder, binder1);
Assert.IsType<MySecondBinder>(binder2);
Assert.Same(defaultBinder, binder3);
}
[Fact]
public void GetBinderThrowsIfModelTypeContainsMultipleAttributes()
{
// Arrange
ModelBinderDictionary binders = new ModelBinderDictionary();
// Act & Assert
Assert.Throws<InvalidOperationException>(
delegate { binders.GetBinder(typeof(ConvertibleTypeWithSeveralBinders), true /* fallbackToDefault */); },
"The type 'System.Web.Mvc.Test.ModelBinderDictionaryTest+ConvertibleTypeWithSeveralBinders' contains multiple attributes that inherit from CustomModelBinderAttribute.");
}
[Fact]
public void GetBinderThrowsIfModelTypeIsNull()
{
// Arrange
ModelBinderDictionary binders = new ModelBinderDictionary();
// Act & Assert
Assert.ThrowsArgumentNull(
delegate { binders.GetBinder(null); }, "modelType");
}
[ModelBinder(typeof(MyFirstBinder))]
private class MyFirstConvertibleType
{
}
private class MyFirstBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
throw new NotImplementedException();
}
}
[ModelBinder(typeof(MySecondBinder))]
private class MySecondConvertibleType
{
}
private class MySecondBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
throw new NotImplementedException();
}
}
[ModelBinder(typeof(MySecondBinder))]
[MySubclassedBinder]
private class ConvertibleTypeWithSeveralBinders
{
}
private class MySubclassedBinderAttribute : CustomModelBinderAttribute
{
public override IModelBinder GetBinder()
{
throw new NotImplementedException();
}
}
}
}
|