2010-01-02 6 views
21

J'ai écrit liant modèle personnalisé dans le projet, qui utilise ASP.NET MVC 2. Cette liaison liant le modèle à 2 champs de modèle:Unité modèle de liaison test personnalisé dans 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); 
    } 
} 

Comment puis-je tester ce classeur modèle en utilisant Standart VS tests unitaires? Passé quelques heures googling, trouver quelques exemples (http://www.hanselman.com/blog/SplittingDateTimeUnitTestingASPNETMVCCustomModelBinders.aspx), mais cet exemple est pour MVC1, et ne fonctionne pas lorsque vous utilisez MVC2.

J'apprécie votre aide.

Répondre

41

J'ai modifié Hanselman's MVC 1 example pour tester ASP.Net MVC 2 classeurs modèle ...

[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

Votre réponse m'a évité de me perdre dans la source MVC. J'ai essayé de faire la même mise à jour et suis arrivé avec presque le même résultat. Malheureusement, je ne définissais pas le 'ModelMetaData' sur le' ModelBindingContext'. Sans cela, vous obtenez un NondReferenceException quelconque sur 'BindModel (ControllerContext controllerContext, ModelBindingContext bindingContext)'. – patridge

+0

Merci pour ça. Il a nettoyé quelques choses pour moi gentiment. –

+0

J'étais sur le point de créer un ValueProvider personnalisé, mais grâce au NameValueCollectionValueProvider que vous avez mentionné. C'était utile. Merci. – Mani

1

L'approche générale consiste à créer une maquette ControllerContext, une maquette ModelBindingContext et un mock PropertyDescriptor, puis à appeler la méthode.

Si votre reliure modèle utilise d'autres services, ce qui semble être le cas pour vous (vous utilisez NHibernate?), Vous devrez les extraire et en fournir des faux-semblants.

Le code de test unitaire ressemblera à quelque chose comme ceci:

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

Quel est le problème (s) êtes-vous avoir écrit le test unitaire?

+0

juste besoin d'un exemple de moqueur ControllerContext, ModelBindingContext et PropertyDescriptor. Oui, Im en utilisant NHibernate, mais je sais comment abstrait et se moquer de cette couche. –

+0

Un problème avec moquer 'ModelBindingContext' est que sa propriété la plus importante (' ModelType') est non-virtuelle, ce qui signifie que les frameworks basés sur l'héritage (par exemple, Moq) ne peuvent pas se moquer de son comportement. –

Questions connexes