2016-01-13 118 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); –