【问题标题】:Testing FluentValidation PropertyValidator测试 FluentValidation PropertyValidator
【发布时间】:2017-07-03 18:28:38
【问题描述】:

是否可以单独测试 FluentValidation PropertyValidator

我知道我可以测试使用 PropertyValidator 的验证器是否存在特定错误,但如果可能的话,我宁愿只在属性验证器上测试真/假。

这可以吗?如果有,怎么做?

【问题讨论】:

  • @wonea 在project site 处查看available test 表明,此处提供的答案与所有​​者用于测试源的答案相匹配。
  • @wonea 并根据相关测试的时间戳,它们至少在过去 2 年内没有改变。

标签: c# validation fluentvalidation


【解决方案1】:

我还想测试我的真/假逻辑。很遗憾 IsValid 方法受到保护。我的解决方法是创建另一个 IsValid 方法并通过受保护的 IsValid 调用它。

public class MyValidator: PropertyValidator 
{
    public MyValidator(
        string errorMessage = "default Message") : base(errorMessage)
    {
    }

    protected override bool IsValid(PropertyValidatorContext context)
    {
        var stringToValidate = context.PropertyValue as String;
        return IsValid(stringToValidate);
    }

    public bool IsValid(string stringToValidate)
    {
        if (stringToValidate == null)
        {
            return false;
        }

        //testing logic here
        return true;
    }
}

【讨论】:

  • Cheers Rich,我希望有另一种不涉及解决方法的方法,但这会给我我需要的东西。再次感谢:)
【解决方案2】:

我知道这已经有一段时间了,但我做到了如下:

自定义验证器:

public class MyValidator : PropertyValidator
{
    public MyValidator ()
        : base("Value must be null or between 0 and 3.")
    {
    }

    protected override bool IsValid(PropertyValidatorContext context)
    {
        if (context.PropertyValue == null)
        {
            return true;
        }

        var value = (decimal)context.PropertyValue;
        return value >= 0m && value <= 3m;
    }
}

测试验证器:

public class TestValidator : InlineValidator<TestObject>
{
    public TestValidator (params Action<TestValidator >[] actions)
    {
        foreach (var action in actions)
        {
            action(this);
        }
    }
}

测试对象:

public class TestObject
{
    public TestObject(decimal? val)
    {
        this.GenericDecimal = val;
    }

    public decimal? GenericDecimal { get; set; }
}

测试:

[Test]
public void TestIt()
{
    var validator = new TestValidator(v => v.RuleFor(obj => obj.GenericDecimal).SetValidator( new MyValidator() ));

    Assert.IsTrue(validator.Validate(new TestObject(null)).IsValid);    
    Assert.IsTrue(validator.Validate(new TestObject(0m)).IsValid);   
    Assert.IsTrue(validator.Validate(new TestObject(3m)).IsValid);   
    Assert.IsFalse(validator.Validate(new TestObject(-1m)).IsValid);   
    Assert.IsFalse(validator.Validate(new TestObject(3.01m)).IsValid);   
}

【讨论】:

    【解决方案3】:

    至于 FluentValidation 6.2 版,由于使 ValidatorSelectors 可全局配置,因此可以构建 PropertyValidator.Validate() 参数:https://github.com/JeremySkinner/FluentValidation/commit/95376c0519da1a06388be91a97fb5062fd4a162e

    在下面的示例中,您将看到我如何验证 Track 的 'puic' 属性

    单元测试:

        public void ExistsInCollectionValidatorTest()
        {
            var track = new Track()
            {
                puic = "p1"
            };
    
            var sut = new ExistsInCollectionValidator<Track>();
    
            // Build PropertyValidator.Validate() parameter
            var selector = ValidatorOptions.ValidatorSelectors.DefaultValidatorSelectorFactory();
            var context = new ValidationContext(track, new PropertyChain(), selector);
            var propertyValidatorContext = new PropertyValidatorContext(context, PropertyRule.Create<Track,string>(t => t.puic), "puic");
    
            var results = sut.Validate(propertyValidatorContext);
            // Assertion..
        }
    

    【讨论】:

      猜你喜欢
      • 2020-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-20
      • 2015-02-03
      相关资源
      最近更新 更多