2008-11-13 6 views

Répondre

41

Vous n'avez pas besoin d'utiliser un Mock si vous utilisez le Pattern du Repository pour vos données, bien sûr.

Quelques exemples: http://www.singingeels.com/Articles/Test_Driven_Development_with_ASPNET_MVC.aspx

// Test for required "FirstName". 
    controller.ViewData.ModelState.Clear(); 

    newCustomer = new Customer 
    { 
     FirstName = "", 
     LastName = "Smith", 
     Zip = "34275",  
    }; 

    controller.Create(newCustomer); 

    // Make sure that our validation found the error! 
    Assert.IsTrue(controller.ViewData.ModelState.Count == 1, 
       "FirstName must be required."); 
+1

Un modificateur virtuel sur les erreurs serait bien, hélas il y a une taxe d'arrangement, qui me semble un peu lourde. –

+0

IMHO Une meilleure solution consiste à utiliser un convoyeur mvc. De cette façon, vous obtenez un comportement plus réaliste de votre contrôleur, vous devez fournir la validation du modèle à son destin - validation des attributs. Ci-dessous le poste décrit cela (http://stackoverflow.com/a/5580363/572612). –

35
//[Required] 
//public string Name { get; set; } 
//[Required] 
//public string Description { get; set; } 

ProductModelEdit model = new ProductModelEdit() ; 
//Init ModelState 
var modelBinder = new ModelBindingContext() 
{ 
    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(
        () => model, model.GetType()), 
    ValueProvider=new NameValueCollectionValueProvider(
         new NameValueCollection(), CultureInfo.InvariantCulture) 
}; 
var binder=new DefaultModelBinder().BindModel(
       new ControllerContext(),modelBinder); 
ProductController.ModelState.Clear(); 
ProductController.ModelState.Merge(modelBinder.ModelState); 

ViewResult result = (ViewResult)ProductController.CreateProduct(null,model); 
Assert.IsTrue(result.ViewData.ModelState["Name"].Errors.Count > 0); 
Assert.True(result.ViewData.ModelState["Description"].Errors.Count > 0); 
Assert.True(!result.ViewData.ModelState.IsValid); 
+0

J'aime vraiment cette méthode. Comme vous le dites, il est préférable de tester correctement un modèle qui a été décoré avec des attributs de validation. – stevethethread

+0

C'est génial! – Ian1971

+0

Très pratique. Je pense que je suis généralement d'accord avec les gens qui disent que vous ne devriez pas tester les propriétés de votre modèle, car cela fait partie du cadre, mais il est parfois crucial de confirmer que votre contrôleur détectera des erreurs critiques. –

0

Ajout aux grandes réponses ci-dessus, consultez cette utilisation fantastique de la méthode TryValidateModel protégée dans la classe de contrôleur.

Créez simplement une classe de test héritant du contrôleur et passez votre modèle à la méthode TryValidateModel. Voici le lien: http://blog.icanmakethiswork.io/2013/03/unit-testing-modelstate.html

Le mérite en revient à John Reilly et Marc Talary pour cette solution.

+2

S'il vous plaît inclure la solution ici plutôt que de lier au large à un blog – csharpsql

+2

Votre lien est mort. –

10

Pour les tests API Web, utilisez la méthode Validate sur le contrôleur:

var controller = new MyController(); 
controller.Configuration = new HttpConfiguration(); 
var model = new MyModel(); 

controller.Validate(model); 
var result = controller.MyMethod(model);