【问题标题】:Testing a validation attribute that depends on another property测试依赖于另一个属性的验证属性
【发布时间】:2016-01-13 11:48:27
【问题描述】:

我创建了一个ValidationAttribute,它基本上检查另一个属性是否有值,如果有,则该属性变为可选。鉴于此属性依赖于另一个属性,我如何才能正确地模拟该属性,我假设 ValidationContext

OptionalIfAttribute

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class OptionalIfAttribute : ValidationAttribute
{
    #region Constructor

    private readonly string otherPropertyName;

    public OptionalIfAttribute(string otherPropertyName)
    {
        this.otherPropertyName = otherPropertyName;
    }

    #endregion

    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("OtherProperty");
    var result = attribute.IsValid(null);

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

【问题讨论】:

    标签: c# asp.net-mvc unit-testing moq


    【解决方案1】:

    这会在没有具体模型类的情况下对其进行测试:

        [TestMethod]
        public void When_BothPropertiesAreSet_SuccessResult()
        {
            var mockModel = new Mock<ISomeModel>();
            mockModel.Setup(m => m.SomeProperty).Returns("something");
            var attribute = new OptionalIfAttribute("SomeProperty");
            var context = new ValidationContext(mockModel.Object, null, null);
    
            var result = attribute.IsValid(string.Empty, context);
    
            Assert.AreEqual(ValidationResult.Success, result);
        }
    
        [TestMethod]
        public void When_SecondPropertyIsNotSet_ErrorResult()
        {
            const string ExpectedErrorMessage = "Whoops!";
    
            var mockModel = new Mock<ISomeModel>();
            mockModel.Setup(m => m.SomeProperty).Returns((string)null);
            var attribute = new OptionalIfAttribute("SomeProperty");
            attribute.ErrorMessage = ExpectedErrorMessage;
            var context = new ValidationContext(mockModel.Object, null, null);
    
            var result = attribute.IsValid(string.Empty, context);
    
            Assert.AreEqual(ExpectedErrorMessage, result.ErrorMessage);
        }
    

    【讨论】:

      【解决方案2】:

      最简单的事情就是这样,

      [Test]
      public void Should_BeValid_WhenPropertyIsNullAndOtherPropertyIsNull()
      {
          var attribute = new OptionalIfAttribute("OtherProperty");
          //**********************
          var model = new testModel;//your model that you want to test the validation against
          var context = new ValidationContext(testModel, null, null);
          var result = attribute.IsValid(testModel, context);
      
          Assert.That(result.Count == 0, Is.True); //is valid or Count > 0 not valid 
      }
      

      【讨论】:

      • 这是在测试模型而不是验证属性
      • 我知道,但你不能测试一个没有另一个,
      • 当然嘲笑ValidationContext 就可以了。
      • 但是您的意图是“创建了一个_ValidationAttribute,它基本上检查另一个属性是否有值,如果有,则该属性变为可选的。”_通过模拟,您将如何证明这一点,因为您得到您的对象来自 - validationContext.ObjectType 和 validationContext.ObjectInstance。始终考虑我的测试证明是什么......
      【解决方案3】:

      我正在使用下面的代码来测试我的自定义验证器类

      [TestMethod]
      public void IsValid_Test()
      {
          var modelObj = new youModelClass {
              requiredProp = value
          };
          var validatorClassObj = new yourValidatorClass();
      
          var validationResult = validatorClassObj.GetValidationResult( valueToValidate, new ValidationContext( modelObj ) );
      
          Assert.AreEqual( ValidationResult.Success, validationResult );
      }
      

      很高兴知道是否有其他测试方法。

      【讨论】:

        猜你喜欢
        • 2012-08-28
        • 1970-01-01
        • 2019-12-17
        • 2020-05-17
        • 2021-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-19
        相关资源
        最近更新 更多