2015-06-27 50 views
5

我對多個模型對象中的某些屬性有類似的規則,我想用自定義屬性驗證器替換它們以避免單元測試中的代碼重複。如何單元測試簡單的屬性有驗證器集?

我有我的財產驗證:

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

,並在型號驗證類佈線起來:

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

試圖測試:

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

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

但測試總是失敗。

那麼,我該如何測試驗證器是否被設置爲屬性ID?

回答

6

您以錯誤的方式使用ShouldHaveChildValidatorId是一個簡單的類型。

ShouldHaveChildValidator正在複雜類型中使用。 (另見source code

測試屬性的正確方法是通過有效的對象和無效的對象,然後varify使用ShouldNotHaveValidationErrorForShouldHaveValidationErrorFor

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

編輯

下面的代碼將執行您正在查找的驗證:

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

} 

我想向你解釋你不應該使用上面的代碼的原因。

當你在UT課堂上,你驗證了類行爲不會受到傷害。

當您創建一個自定義的驗證,創建一個類有責任覈實具體型號( - >業務規則)...

Id是一個簡單的類型與根據他的父模型業務規則。 因此,您需要通過模型驗證程序驗證Id的業務規則。

我們假設您的某個模型突然需要更改。在這種情況下,您沒有任何驗證證明您現有的任何業務規則不會受到傷害(或者您決定在IntIdPropertyValidator內進行更改,即使您不想這樣做,此舉也會影響到任何地方)。

創建自定義Property Validator對代碼維護非常有用,但是,測試應該針對模型驗證器。

在複雜類型的故事是完全不同的:

一般複雜類型都有自己的業務規則。在這種情況下,您必須爲它們創建自定義驗證程序,然後驗證父驗證程序是否使用正確的驗證程序。另一件要驗證的事情是:如果複雜類型是Null或複雜規則,例如「當屬性值爲X,然後複雜類型狀態爲Y」時......

+0

嗯,是的,我知道,這就是我自己測試自定義驗證器的方式。但問題是,現在我不想爲每個具有驗證者支持的模型類都這樣做。我想測試驗證器是否真正爲prop設置,如果它工作正確則不測試它,因爲這是自定義驗證器的測試所做的。 – liri2006

+0

@ liri2006我用一種方式更新了我的答案,以進行您正在查找的驗證...我也解釋了爲什麼您不應該這樣做...... –

+0

這非常有幫助!代碼和解釋。 – liri2006