2012-08-06 17 views
14

Estoy participando en un proyecto que usa ASP.NET MVC 3 y DataAnnotations. Tenemos DataAnnotaciones en clases ViewModels.TDD: ¿Cuál es la mejor práctica para probar las anotaciones de datos en ASP.NET MVC 3?

¿Cómo se escriben las pruebas unitarias para estas validaciones?

ViewModel ejemplo:

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; } 
} 

Gracias!

+1

¿Qué hacen estas anotaciones de datos? ¿Es validación o algo más? –

+0

Marca algún componente para ser validado. Un ejemplo práctico de validación manual con anotaciones de datos: http://odetocode.com/blogs/scott/archive/2011/06/29/manual-validation-with-data-annotations.aspx –

Respuesta

3

Dado que esas anotaciones son muy declarativas, tiene poco sentido escribir pruebas unitarias que simplemente comprueben (con reflejo) que los métodos están anotados: las pruebas simplemente duplicarían el código de producción. Y eso aún dejaría la posibilidad de que las anotaciones no se usen de la manera en que el marco espera que se usen (tal vez sean las anotaciones incorrectas, estén en el lugar equivocado o les falte alguna configuración adicional).

Por lo tanto, una prueba significativa no sería una prueba unitaria, sino una prueba de integración que asegura que el sistema está detectando las anotaciones correctamente. Para mantener la velocidad razonable, intente hacer que las pruebas de integración estén lo más enfocadas posible, instanciando lo menos posible del marco (lo que requiere un conocimiento profundo del marco: RTFS). Si nada más, una prueba de extremo a extremo podría verificar el uso correcto de las anotaciones al analizar el HTML y verificar que los errores de validación se muestren cuando se ingresan datos no válidos en los campos.

Debería ser necesario escribir solo un par de pruebas de integración/extremo a extremo para asegurarse de que la validación se haya habilitado. No debería haber necesidad de probar cada campo, cuando todos funcionan de la misma manera.

15

El .NET framework viene con una clase Validator que puede ejercer su lógica de validación de forma aislada. El código para probar podría verse así:

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.")); 

No hay necesidad de herramientas personalizadas para buscar la existencia de atributos. La clase Validator hace el trabajo por usted y completa una colección ValidationResult igual que la infraestructura MVC.

Puede encontrar un buen informe sobre este método en K. Scott Allen's blog.

+0

Gran respuesta. Esta es la manera perfecta de probar la unidad. Puedo verificar que la validación ocurrió sin tener que especificar manualmente qué es lo que la valida. –

+1

Lo recomendaría a la colección 'results.Clear()' antes de usarlo nuevamente en 'TryValidationObject()'. –

Cuestiones relacionadas