Tôi đã viết một số chất kết dính mô hình tùy chỉnh (triển khai IModelBinder) trong ứng dụng ASP.NET MVC của chúng tôi. Tôi tự hỏi một cách tiếp cận tốt để unittest chúng (chất kết dính) là gì?Làm cách nào để kiểm tra Trình mô hình hóa tùy chỉnh trong ASP.NET MVC?
Trả lời
tôi đã làm nó theo cách này:
var formElements = new NameValueCollection() { {"FirstName","Bubba"}, {"MiddleName", ""}, {"LastName", "Gump"} };
var fakeController = GetControllerContext(formElements);
var valueProvider = new Mock<IValueProvider>();
var bindingContext = new ModelBindingContext(fakeController, valueProvider.Object, typeof(Guid), null, null, null, null);
private static ControllerContext GetControllerContext(NameValueCollection form) {
Mock<HttpRequestBase> mockRequest = new Mock<HttpRequestBase>();
mockRequest.Expect(r => r.Form).Returns(form);
Mock<HttpContextBase> mockHttpContext = new Mock<HttpContextBase>();
mockHttpContext.Expect(c => c.Request).Returns(mockRequest.Object);
return new ControllerContext(mockHttpContext.Object, new RouteData(), new Mock<ControllerBase>().Object);
}
Và sau đó tôi chỉ thông qua trong biến BindingContext với phương pháp BindModel của đối tượng mà thực hiện giao diện IModelBinder.
Đây là một cách không-mocks đơn giản tôi đã viết cho bạn trên blog của tôi giả sử bạn sử dụng ValueProvider và không phải là HttpContext: http://www.hanselman.com/blog/SplittingDateTimeUnitTestingASPNETMVCCustomModelBinders.aspx
[TestMethod]
public void DateTime_Can_Be_Pulled_Via_Provided_Month_Day_Year_Hour_Minute_Second_Alternate_Names()
{
var dict = new ValueProviderDictionary(null) {
{ "foo.month1", new ValueProviderResult("2","2",null) },
{ "foo.day1", new ValueProviderResult("12", "12", null) },
{ "foo.year1", new ValueProviderResult("1964", "1964", null) },
{ "foo.hour1", new ValueProviderResult("13","13",null) },
{ "foo.minute1", new ValueProviderResult("44", "44", null) },
{ "foo.second1", new ValueProviderResult("01", "01", null) }
};
var bindingContext = new ModelBindingContext() { ModelName = "foo", ValueProvider = dict };
DateAndTimeModelBinder b = new DateAndTimeModelBinder() { Month = "month1", Day = "day1", Year = "year1", Hour = "hour1", Minute = "minute1", Second = "second1" };
DateTime result = (DateTime)b.BindModel(null, bindingContext);
Assert.AreEqual(DateTime.Parse("1964-02-12 13:44:01"), result);
}
Đây là [cập nhật MVC 2 của câu trả lời này] (http://stackoverflow.com/questions/1992629/unit-testing-custom-model-binder-in-asp-net-mvc-2/2310954#2310954) cho bất kỳ ai người kết thúc ở đây trước khi họ tìm thấy. – patridge
dict có thể được refactored như thế này
FormCollection form = new FormCollection
{
{ "month1", "2" },
{ "day1", "12" },
{ "year1", "1964" },
{ "hour1", "13" },
{ "minute1", "44" },
{ "second1", "01" }
};
var bindingContext = new ModelBindingContext() { ModelName = "foo", ValueProvider = form.ToValueProvider() };
Các contructor quá tải được sử dụng cho ModelBindingContext dường như không tồn tại. –
Vâng, tôi chỉ sử dụng constructor parameterless và sau đó gọi BindModel trực tiếp với ControllerContext giả lập. Dường như làm việc cho đến nay. –