2015-06-27 15 views
5

Ho regole simili per alcune proprietà in più oggetti del modello e voglio sostituirli con validatori di proprietà personalizzate per evitare la duplicazione del codice nei test unitari.Come testare la proprietà semplice ha set di validatori?

devo la mia proprietà validatore:

public class IntIdPropertyValidator: PropertyValidator 
{ 
    public IntIdPropertyValidator() 
     : base("Property {PropertyName} should be greater than 0") 
    { 
    } 

    protected override bool IsValid(PropertyValidatorContext context) 
    { 
     var value = (int)context.PropertyValue; 

     return value > 0; 
    } 
} 

e il cablaggio è nel modello di classe di convalida:

public class SomeRequestValidator : AbstractValidator<CreateWordRequest> 
{ 
    public SomeRequestValidator() 
    { 
     RuleFor(x => x.Id).SetValidator(new IntIdPropertyValidator()); 
    } 
} 

cercato di prova:

[Test] 
public void Validate_IdHasValidator_Success() 
{ 
    Init(); 

    validator.ShouldHaveChildValidator(x => x.Id, typeof(IntIdPropertyValidator)); 
} 

Ma prova fallisce sempre.

Quindi, come posso verificare che il validatore sia effettivamente impostato per l'ID di proprietà?

risposta

6

Si sta utilizzando ShouldHaveChildValidator nel modo sbagliato. Id è un tipo semplice.

ShouldHaveChildValidator è in uso su tipi complessi. (Vedi anche la source code)

Il modo giusto per testare la proprietà è di passare oggetti validi e oggetti non validi e poi varify utilizzando ShouldNotHaveValidationErrorFor e ShouldHaveValidationErrorFor:

[Test] 
public void Should_have_error_when_Id_Is_Ilegal() { 
     validator.ShouldHaveValidationErrorFor(p => p.Id, new CreateWordRequest()); 
} 

[Test] 
public void Should_not_have_error_when_Id_Is_Legal() { 
     validator.ShouldNotHaveValidationErrorFor(p => p.Id, new CreateWordRequest() 
                  { 
                   Id = 7 
                  }); 
} 

Modifica

Il codice seguente farà la verifica che stavi cercando:

[Test] 
public void Validate_IdHasValidator_Success() 
{ 
    var validator = new SomeRequestValidator(); 

    var descriptor = validator.CreateDescriptor(); 
    var matchingValidators = descriptor.GetValidatorsForMember(
       Extensions.GetMember<CreateWordRequest, int>(x => x.Id).Name); 

    Assert.That(matchingValidators.FirstOrDefault(), Is.InstanceOf<IntIdPropertyValidator>()); 

} 

Mi piacerebbe spiegarti il ​​motivo per cui non dovresti usare il codice sopra.

Quando si esegue la classe UT, verificare che il comportamento della classe non venga danneggiato.

Quando si crea un validatore personalizzato, si crea una classe con la responsabilità di verificare il modello specifico (-> regole di business) ...

Id è un tipo semplice con regole di business secondo il suo modello di genitore . Pertanto è necessario verificare le regole aziendali di Id tramite il validatore del modello.

Supponiamo che uno dei tuoi modelli debba improvvisamente cambiare. In questo caso non hai alcuna convalida che nessuna delle tue regole commerciali esistenti possa essere lesa (o se decidi di apportare modifiche all'interno di IntIdPropertyValidator, tale spostamento avrà effetto ovunque, anche se non lo desideri).

Creazione di una personalizzata Property Validator è molto buona per la manutenzione del codice, tuttavia, i test dovrebbero essere contro il validatore del modello.

Sulla tipi complessi della storia è ben diversa:

tipi solito complesso ha le proprie regole di business. In questo caso, devi creare un validatore personalizzato per loro e quindi verificare che il validatore principale utilizzi il validatore giusto. Un'altra cosa da verificare è: Se il tipo complesso è Null o regole complesse come "quando il valore della proprietà è X e lo stato del tipo complesso è Y" ...

+0

Beh, sì, lo so, ed è così che ho testato autonomamente il validatore personalizzato. Ma il punto è che ora non voglio farlo per ogni classe di modello che ha il sostegno con quel validatore. Voglio testare se il validatore è effettivamente impostato per il prop, e non testarlo se funziona correttamente, perché è quello che fanno i test del validatore personalizzato. – liri2006

+0

@ liri2006 Ho aggiornato la mia risposta con un modo per fare la verifica che stavi cercando ... Spiego anche perché non dovresti farlo ... –

+0

E 'stato estremamente utile! Sia il codice che la spiegazione. – liri2006