2010-01-02 15 views
21

ja napisałem zwyczaj modelu spoiwo w projekcie, który używa ASP.NET MVC 2. Ten model spoiwa wiążą się zaledwie 2 Obszary modelu:Unit Testing zwyczaj modelu spoiwo w 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); 
    } 
} 

Jak czy mogę przetestować ten model spoiwa przy użyciu standardowych testów VS? Spędziłem kilka godzin googlowania, znajdowałem kilka przykładów (http://www.hanselman.com/blog/SplittingDateTimeUnitTestingASPNETMVCCustomModelBinders.aspx), ale te przykłady dotyczą MVC1 i nie działają podczas używania MVC2.

Doceniam twoją pomoc.

Odpowiedz

41

Mam zmodyfikowany Hanselman's MVC 1 example przetestować ASP.Net MVC 2 Model spoiw ...

[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

Twoja odpowiedź uratowała mnie przed zbieraniem się w źródle MVC. Próbowałem wykonać tę samą aktualizację i otrzymałem prawie taki sam wynik. Niestety, nie ustawiłem 'ModelMetaData' na' ModelBindingContext'. Bez niego otrzymasz nijakie 'NullReferenceException' na' BindModel (ControllerContext controllerContext, TextBindingContext bindingContext) '. – patridge

+0

Dzięki za to. Oczyściło mi to trochę rzeczy. –

+0

Miałem zamiar utworzyć niestandardowy ValueProvider, ale dzięki NameValueCollectionValueProvider, o którym już wspomniałeś. To było przydatne. Dzięki. – Mani

1

Ogólne podejście polega na stworzeniu pozornego ControllerContext, makiety ModelBindingContext i makiety PropertyDescriptor, a następnie wywołanie metody.

Jeśli Twój segregator korzysta z innych usług, które wygląda na Twoje (używasz NHibernate?), Będziesz musiał je streścić i podać ich również.

Jednostka kodu testu będzie wyglądać następująco:

// 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 

Jaki problem (y) Czy masz pisanie testów jednostkowych?

+0

Wystarczy przykład szyderczy ControllerContext, ModelBindingContext i PropertyDescriptor. Tak, używam NHibernate, ale wiem, jak abstrakcyjna i kpią z tej warstwy. –

+0

Jednym z problemów z wyśmiewaniem "ModelBindingContext" jest to, że jego najważniejsza właściwość ("ModelType") jest nie-wirtualna, co oznacza, że ​​oparte na dziedziczeniu frameworki (np. Moq) nie mogą kpić z jego zachowania. –

Powiązane problemy