2010-01-02 28 views
21

Tôi đã viết binder mô hình tùy chỉnh trong dự án, sử dụng ASP.NET MVC 2. model binder này ràng buộc chỉ 2 lĩnh vực mô hình:Unit mô hình thử nghiệm tùy chỉnh chất kết dính trong ASP.NET MVC 2

public class TaskFormBinder : DefaultModelBinder 
{ 
    protected override void BindProperty(ControllerContext controllerContext, 
     ModelBindingContext bindingContext, 
     PropertyDescriptor propertyDescriptor) 
    {   
     if (propertyDescriptor.Name == "Type") 
     { 
      var value = bindingContext.ValueProvider.GetValue("Type"); 
      var typeId = value.ConvertTo(typeof(int)); 
      TaskType foundedType; 
      using (var nhSession = Domain.GetSession()) 
      { 
       foundedType = nhSession.Get<TaskType>(typeId); 
      } 
      if (foundedType != null) 
      { 
       SetProperty(controllerContext, bindingContext, propertyDescriptor, foundedType); 
      } 
      else 
      { 
       AddModelBindError(bindingContext, propertyDescriptor); 
      } 
      return; 
     } 
     if (propertyDescriptor.Name == "Priority") 
     { /* Other field binding ... */ 
      return; 
     } 
     base.BindProperty(controllerContext, bindingContext, propertyDescriptor); 
    } 
} 

thế nào tôi có thể kiểm tra chất kết dính mô hình này bằng cách sử dụng thử nghiệm đơn vị VS standart? Dành một vài giờ googling, tìm vài ví dụ (http://www.hanselman.com/blog/SplittingDateTimeUnitTestingASPNETMVCCustomModelBinders.aspx), nhưng ví dụ này là dành cho MVC1, và không làm việc khi sử dụng MVC2.

Tôi đánh giá cao sự trợ giúp của bạn.

Trả lời

41

Tôi đã sửa đổi Hanselman's MVC 1 example để kiểm tra ASP.Net MVC chất kết dính 2 mô hình ...

[Test] 
public void Date_Can_Be_Pulled_Via_Provided_Month_Day_Year() 
{ 
    // Arrange 
    var formCollection = new NameValueCollection { 
     { "foo.month", "2" }, 
     { "foo.day", "12" }, 
     { "foo.year", "1964" } 
    }; 

    var valueProvider = new NameValueCollectionValueProvider(formCollection, null); 
    var modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(FwpUser)); 

    var bindingContext = new ModelBindingContext 
    { 
     ModelName = "foo", 
     ValueProvider = valueProvider, 
     ModelMetadata = modelMetadata 
    }; 

    DateAndTimeModelBinder b = new DateAndTimeModelBinder { Month = "month", Day = "day", Year = "year" }; 
    ControllerContext controllerContext = new ControllerContext(); 

    // Act 
    DateTime result = (DateTime)b.BindModel(controllerContext, bindingContext); 

    // Assert 
    Assert.AreEqual(DateTime.Parse("1964-02-12 12:00:00 am"), result); 
} 
+0

Câu trả lời của bạn đã cứu tôi khỏi việc nhét xung quanh trong nguồn MVC. Tôi đã cố gắng thực hiện cập nhật tương tự và đưa ra kết quả tương tự. Thật không may, tôi đã không thiết lập 'ModelMetaData' trên' ModelBindingContext'. Nếu không có nó, bạn sẽ nhận được một NullReferenceException' không xác định trên 'BindModel (ControllerContext controllerContext, ModelBindingContext bindingContext)'. – patridge

+0

Cảm ơn vì điều này. Nó xóa một số điều cho tôi độc đáo. –

+0

Tôi sắp tạo một ValueProvider tùy chỉnh, nhưng nhờ NameValueCollectionValueProvider mà bạn đã đề cập. Điều này rất hữu ích. Cảm ơn. – Mani

1

Cách tiếp cận chung là tạo một ControllerContext giả lập, mô hình hóa ModelBindingContext, và mô phỏng PropertyDescriptor, và sau đó gọi phương thức.

Nếu trình kết nối mô hình của bạn sử dụng các dịch vụ khác, nó giống như dịch vụ của bạn (bạn đang sử dụng NHibernate?), Thì bạn sẽ phải trừu tượng hóa những dịch vụ đó và cung cấp mocks của chúng.

Đơn vị mã kiểm tra sẽ giống như thế này:

// Arrange 
ControllerContext mockControllerContext = ...; 
ModelBindingContext mockModelBindingContext = ...; 
PropertyDescriptor mockPropertyDescriptor = ...; 
SomeService mockService = ...; 

TaskFormBinder taskFormBinder = new TaskFormBinder(); 
taskFormBinder.Service = mockService; 

// Act 
taskFormBinder.BindProperty(
    mockControllerContext, mockModelBindingContext, mockPropertyDescriptor); 

// Assert 
// ... here you need to inspect the values in the model binding context to see that it set the right properties 

vấn đề gì (s) bạn đang gặp bằng văn bản cho đơn vị kiểm tra?

+0

Chỉ cần một ví dụ về chế giễu ControllerContext, ModelBindingContext và PropertyDescriptor. Có, Im sử dụng NHibernate, nhưng tôi biết cách trừu tượng và giả lập lớp này. –

+0

Một vấn đề với chế nhạo 'ModelBindingContext' là thuộc tính quan trọng nhất của nó (' ModelType') là không ảo, có nghĩa là các khung dựa trên kế thừa (ví dụ, Moq) không thể giả lập hành vi của nó. –

Các vấn đề liên quan