2012-09-01 12 views
7

Tengo una clase de prueba con un par de pruebas que comprueban si la entidad IsValid. Pasé a usar IValidatableObject para tener mi propia validación personalizada, pero estoy atascado con la técnica de validación correcta.IValidatableObject pasa la validación, pero StringLength no es válido

Esta es mi clase de prueba:

[TestFixture] 
public class StudentTests { 
    private static Student GetContactWithContactInfo() 
    { 
     return new Student(new TestableContactRepository()) 
          { 
           Phone = "7275551111" 
          }; 
    } 

    private static Student GetContactWithoutContactInfo() 
    { 
     return new Student(new TestableContactRepository()); 
    } 

    [Test] 
    public void Student_Saving_StudentHasInfo_IsValid() 
    { 
     // Arrange 
     Student student = GetContactWithContactInfo(); 
     // Act 
     student.Save(); 
     // Assert 
     Assert.IsTrue(student.IsValid); 
    } 

    [Test] 
    public void Student_Saving_StudentDoesNotHaveInfo_IsNotValid() 
    { 
     // Arrange 
     Student student = GetContactWithoutContactInfo(); 
     // Act 
     student.Save(); 
     // Assert 
     Assert.IsFalse(student.IsValid); 
    } 
} 

Este es mi entidad:

public class Student : IValidatableObject 
{ 
    private readonly IContactRepository contactRepository; 

    public Student(IContactRepository _contactRepository) 
    { 
     contactRepository = _contactRepository; 
     Contacts = new List<Student>(); 
    } 

    [Required] 
    public int Id { get; private set; } 

    [StringLength(10, MinimumLength = 10)] 
    public string Phone { get; set; } 


    public List<Student> Contacts { get; private set; } 

    public bool IsValid { get; private set; } 

    public void Save() 
    { 
     if (IsValidForPersistance()) 
     { 
      IsValid = true; 
      Id = contactRepository.Save(); 
     } 
    } 

    private bool IsValidForPersistance() 
    { 
     return Validator.TryValidateObject(this, new ValidationContext(this), null, true); 
    } 

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
     if (string.IsNullOrEmpty(Phone) && Contacts.All(c => string.IsNullOrEmpty(c.Phone))) 
      yield return new ValidationResult("The student or at least one contact must have a phone number entered", new[] { "Phone Number" }); 
    } 
} 

Como se puede ver el examen de las pruebas IsValid llamando al IsValidForPersistance. Validate eventualmente tendrá más validación.

Todas las pruebas anteriores pasan con este método, pero esta prueba también se aprueba pero no debe.

[Test] 
public void Student_Saving_HasContactInfoWithInvalidLength_IsNotValid() 
{ 
    // Arrange 
    Contact student = GetContactWithoutContactInfo(); 
    student.Phone = "string"; 

    // Act 
    student.Save(); 

    // Assert 
    Assert.IsFalse(student.IsValid); 
} 

Aquí estoy configurando mi propio valor Phone de una cadena de longitud no válida. Espero que la validación falle debido a la anotación StringLength establecida con un mínimo de 10 caracteres.

¿Por qué pasa esto?

Actualización Hubo un problema con la validación personalizada, se actualizó el código con el cambio. Junto con la sugerencia de nemesv de no tener un modificador private en la propiedad Phone, ahora funciona. He actualizado todo el código para que funcione.

+0

Estoy buscando en este enlace en este momento, ya que tiene una demo proyecto. El proyecto implementa algunas clases auxiliares adicionales que funcionan con Validator. http://www.codeproject.com/Articles/256183/DataAnnotations-Validation-for-Beginner –

Respuesta

13

Validator.TryValidateObjectsólo comprueba los RequiredAttribute s (y también otras cosas como atributos de nivel de tipo y IValidatableObject aplicación por defecto).

Si necesita validar todos los atributos como StringLength etc. tiene que establecer el parámetro validateAllProperties del método para true

private bool IsValidForPersistance() { 
    return Validator.TryValidateObject(this, 
             new ValidationContext(this), 
             null, 
             true /* validateAllProperties */); 
} 
+0

He actualizado mi código y tengo el valor 'validateAllProperties' establecido en verdadero ahora pero todavía obtengo el mismo resultado. Esa misma prueba todavía pasa como si fuera válida –

+0

Tu código funciona para mí con 'validateAllProperties = true'. Solo he cambiado una cosa en la propiedad del teléfono 'public string Phone {private get; conjunto; } 'He hecho que se haga público así que debería ser' public string Phone {get; conjunto; } ' – nemesv

Cuestiones relacionadas