2012-09-01 16 views
7

Ho una classe di test con un paio di test che verificano se l'entità è IsValid. Mi sono trasferito a utilizzare IValidatableObject da avere la mia convalida personalizzata ma sono bloccato con la tecnica di convalida corretta.IValidatableObject passa la convalida ma StringLength non è valido

Questa è la mia classe Test:

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

Questo è il mio soggetto:

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

Come si può vedere il test test per IsValid chiamando il IsValidForPersistance. Validate alla fine avrà più validazione.

I test precedenti passano tutti utilizzando questo metodo, ma questo test di seguito passa anche ma non dovrebbe.

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

    // Act 
    student.Save(); 

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

Qui sto impostando la mia Phone valore di una stringa di lunghezza non valida. Mi aspetto che la convalida non vada a buon fine a causa dell'annotazione StringLength impostata su min e max 10 caratteri.

Perché è questo passaggio?

Aggiornamento Si è verificato un problema con la convalida personalizzata, ha aggiornato il codice con la modifica. Insieme al suggerimento di nemesv di non avere un modificatore private sulla proprietà Phone ora funziona. Ho aggiornato tutto il codice per funzionare.

+0

sto cercando in questo link in questo momento in quanto ha una demo progetto. Il progetto implementa alcune classi di helper aggiuntive che funzionano con il Validator. http://www.codeproject.com/Articles/256183/DataAnnotations-Validation-for-Beginner –

risposta

13

Validator.TryValidateObjectcontrolla solo le RequiredAttribute s (e anche altre cose, come gli attributi di livello di tipo e IValidatableObject implementazione) per impostazione predefinita.

se avete bisogno di validare tutti gli attributi come StringLength ecc è necessario impostare il parametro validateAllProperties del metodo per true

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

Ho aggiornato il mio codice e ho impostato il valore 'validateAllProperties' su true ora, ma ottengo lo stesso risultato. Lo stesso test passa ancora come se fosse valido –

+0

Il codice funziona per me con 'validateAllProperties = true'. Solo una cosa che ho cambiato nella proprietà Phone 'public string Phone {private get; impostato; } 'Ho reso pubblico il pubblico, quindi dovrebbe essere' public string Phone {get; impostato; } ' – nemesv

Problemi correlati