2012-08-06 6 views
14

Parteciperò a un progetto utilizzando ASP.NET MVC 3 e DataAnnotations. Abbiamo datiAnnotazioni nelle classi ViewModels.TDD: Qual è la procedura migliore per testare DataAnnotations in ASP.NET MVC 3?

Come si scrivono i test di unità per queste convalide?

ViewModel esempio:

public class AchievementVM 
{ 
    [Required(ErrorMessage = "The title field is required.")] 
    [StringLength(100, ErrorMessage = "Title must be 100 characters or less.")] 
    public string Title { get; set; } 
} 

Grazie!

+1

Cosa fanno queste annotazioni di dati? È convalida o qualcos'altro? –

+0

Segnala alcuni componenti da convalidare. Un esempio pratico di convalida manuale con annotazioni di dati: http://odetocode.com/blogs/scott/archive/2011/06/29/manual-validation-with-data-annotations.aspx –

risposta

3

Dal momento che quelle annotazioni sono molto dichiarative, non ha molto senso scrivere dei test di unità che controllano (con la riflessione) che i metodi siano annotati - i test semplicemente duplicano il codice di produzione. E ciò lascerebbe comunque la possibilità che le annotazioni non vengano utilizzate nel modo in cui il framework si aspetta che vengano utilizzate (forse sono annotazioni sbagliate, sono nel posto sbagliato o mancano alcune configurazioni aggiuntive).

Quindi un test significativo non sarebbe un test unitario, ma un test di integrazione che assicura che il sistema rilevi correttamente le annotazioni. Per mantenere la velocità ragionevole, cerca di rendere i test di integrazione il più mirati possibile, istanziando il meno possibile il framework (che richiede una conoscenza approfondita del framework - RTFS). Se non altro, un test end-to-end potrebbe verificare l'uso corretto delle annotazioni analizzando l'HTML e controllando che gli errori di validazione vengano mostrati quando i dati non validi vengono inseriti nei campi.

Dovrebbe essere necessario scrivere solo un paio di test di integrazione/end-to-end per assicurarsi che la convalida sia stata abilitata. Non dovrebbe essere necessario testare ogni singolo campo, quando tutti funzionano allo stesso modo.

15

Il framework .NET viene fornito con una classe Validator che può esercitare la logica di convalida in isolamento. Il codice da testare potrebbe essere il seguente:

var achievement = new AchievementVM(); 
var context = new ValidationContext(achievement, 
    serviceProvider: null, items: null); 
var results = new List<ValidationResult>(); 

var isValid = Validator.TryValidateObject(achievement, context, results, true); 

Assert.IsTrue(results.Any(vr => vr.ErrorMessage == "The title field is required.")); 

achievement.Title = "Really really long title that violates " 
    + "the range constraint and should not be accepted as " 
    + "valid input if this has been done correctly."; 

Validator.TryValidateObject(achievement, context, results, true); 

Assert.IsTrue(results.Any(vr => vr.ErrorMessage == "Title must be 100 characters or less.")); 

Nessuna necessità di utilità personalizzate per cercare l'esistenza di attributi. La classe Validator esegue il lavoro automaticamente e popola una raccolta ValidationResult uguale all'infrastruttura MVC.

Una buona annotazione su questo metodo è disponibile su K. Scott Allen's blog.

+0

Ottima risposta. Questo è il modo perfetto per testare le unità. Posso verificare che la convalida sia avvenuta senza dover specificare manualmente cosa la sta convalidando. –

+1

Vorrei raccomandare la raccolta 'results.Clear()' prima di riutilizzarla in 'TryValidationObject()'. –