2016-01-13 97 views
3

我在測試自定義驗證屬性時遇到了一些麻煩。由於方法簽名是protected,當我在單元測試中調用IsValid方法時,我無法傳入Mock<ValidationContext>對象,而是調用基地virtual bool IsValid(object value)測試覆蓋IsValid的ValidationAttribute

ValidationAttribute

protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
{ 
    var otherPropertyInfo = validationContext.ObjectType.GetProperty(this.otherPropertyName); 
    var otherPropertyValue = otherPropertyInfo.GetValue(validationContext.ObjectInstance, null); 

    if (value != null) 
    { 
     if (otherPropertyValue == null) 
     { 
      return new ValidationResult(FormatErrorMessage(this.ErrorMessage)); 
     } 
    } 

    return ValidationResult.Success; 
} 

測試

[Test] 
public void Should_BeValid_WhenPropertyIsNullAndOtherPropertyIsNull() 
{ 
    var attribute = new OptionalIfAttribute("test"); 
    var result = attribute.IsValid(null); 

    Assert.That(result, Is.True); 
} 

如果我無法在嘲笑驗證背景下通過,那我怎麼才能正確地測試這個類?

回答

4

您可以使用Validator類手動執行驗證,而不必模擬任何內容。有一個簡短的文章here。我可能會做一些像

[Test] 
public void Should_BeValid_WhenPropertyIsNullAndOtherPropertyIsNull() 
{ 
    var target = new ValidationTarget(); 
    var context = new ValidationContext(target); 
    var results = new List<ValidationResult>(); 

    var isValid = Validator.TryValidateObject(target, context, results); 

    Assert.That(isValid, Is.True); 
} 

private class ValidationTarget 
{ 
    public string X { get; set; } 

    [OptionalIf(nameof(X))] 
    public string OptionalIfX { get; set; } 
} 

你可以任意作出results斷言。

+0

這是我事實上最終做的,但忘了把答案放在這裏。 – ediblecode

+0

您應該在Validator.TryValidateObject中設置validateAllProperties arg,否則它不檢查特性,var isValid = Validator.TryValidateObject(target,context,results,true); –