2011-01-12 8 views
26

Tengo un atributo de validación de clase de mvc asp.net personalizado. Mi pregunta es ¿cómo puedo probarla en una unidad? Sería una cosa probar que la clase tiene el atributo, pero esto en realidad no probaría esa lógica dentro de él. Esto es lo que quiero probar.¿Cómo puedo probar la unidad de mi atributo de validación personalizada?

[Serializable] 
[EligabilityStudentDebtsAttribute(ErrorMessage = "You must answer yes or no to all questions")] 
public class Eligability 
{ 
    [BooleanRequiredToBeTrue(ErrorMessage = "You must agree to the statements listed")] 
    public bool StatementAgree { get; set; } 

    [Required(ErrorMessage = "Please choose an option")] 
    public bool? Income { get; set; } 

..... eliminado por razones de brevedad }

[AttributeUsage(AttributeTargets.Class)] 
public class EligabilityStudentDebtsAttribute : ValidationAttribute 
{ 
    // If AnyDebts is true then 
    // StudentDebts must be true or false 

    public override bool IsValid(object value) 
    { 
     Eligability elig = (Eligability)value; 
     bool ok = true; 
     if (elig.AnyDebts == true) 
     { 
      if (elig.StudentDebts == null) 
      { 
       ok = false; 
      } 
     } 
     return ok; 

    } 
} 

He tratado de escribir una prueba de la siguiente manera, pero esto no funciona:

[TestMethod] 
public void Eligability_model_StudentDebts_is_required_if_AnyDebts_is_true() 
{ 

    // Arrange 
    var eligability = new Eligability(); 
    var controller = new ApplicationController(); 

    // Act 
    controller.ModelState.Clear(); 
    controller.ValidateModel(eligability); 
    var actionResult = controller.Section2(eligability,null,string.Empty); 

    // Assert 
    Assert.IsInstanceOfType(actionResult, typeof(ViewResult)); 
    Assert.AreEqual(string.Empty, ((ViewResult)actionResult).ViewName); 
    Assert.AreEqual(eligability, ((ViewResult)actionResult).ViewData.Model); 
    Assert.IsFalse(((ViewResult)actionResult).ViewData.ModelState.IsValid); 
} 

El ModelStateDictionary no lo hace contiene la clave para este atributo personalizado. Solo contiene los atributos para los atributos de validación estándar.

¿Por qué es esto?

¿Cuál es la mejor manera de probar estos atributos personalizados?

Respuesta

35

Su atributo EligabilityStudentDebtsAttribute es solo una clase estándar, como todo lo demás, solo pruebe el método IsValid(). Si funciona bien, confíe en Framework ese atributo funciona bien.

Así:

[Test] 
public void AttibuteTest() 
{ 
    // arrange 
    var value = //.. value to test - new Eligability() ; 
    var attrib = new EligabilityStudentDebtsAttribute(); 

    // act 
    var result = attrib.IsValid(value); 

    // assert 
    Assert.That(result, Is.True) 
} 
+0

Doh! ¡Por supuesto! – MightyAtom

+1

¿Es esta la mejor manera de hacer la validación de propiedad cruzada? (Validación del modelo que involucra más de una propiedad) – MightyAtom

+0

manténgalo simple ... intente, si funciona para usted - no hay razón para realizar más pruebas de compex :) –

6

Su atributo de validación personalizada podría ser dependiente del estado de otras propiedades. En este caso, puede usar los métodos estáticos System.ComponentModel.DataAnnotations.Validator, por ejemplo:

var model = ... 
var context = new ValidationContext(model); 
var results = new List<ValidationResult>(); 
var isValid = Validator.TryValidateObject(model, context, results, true); 
Assert.True(isValid); 
+1

es posible que desee agregar el indicador verdadero para validar todas las propiedades: "Validator.TryValidateObject (modelo, contexto, resultados, verdadero);" - Tuve problemas al probar mi validación con NUnit, la validación dentro de "anulación protegida ValidationResult IsValid (..)" no se ejecutó a menos que proporcioné el valor "validateAllProperties" como verdadero; por lo tanto, las pruebas no se ejecutaron como se esperaba y no pude depurar en mi código. – JimiSweden

Cuestiones relacionadas