9

当我们正在验证的对象具有也在验证的子类时,是否可以为 fluentvalidation 类编写单元测试。

举个例子:我的课看起来像这样

public class TestModel
{

    public class SubData
    {
        public int SubDataVal { get; set; }
    }

    public int ParentVal { get; set; }
    public SubData Sub { get; set; }

}

我的验证逻辑如下所示:

public class TestModelValidator : AbstractValidator<TestModel>
{
    public TestModelValidator()
    {
        RuleFor(o => o.ParentVal).GreaterThan(0);
        RuleFor(o => o.Sub.SubDataVal).GreaterThan(0);
    }
}

当我编写以下单元测试时

    [Test]
    public void Should_have_error_when_val_is_zero()
    {
        validator = new TestModelValidator();
        validator.ShouldHaveValidationErrorFor(model => model.ParentVal, 0);
    }

我收到“System.NullReferenceException:对象引用未设置为对象的实例”。FluentValidation.TestHelper.ValidatorTester`2.ValidateError(T instanceToValidate)的异常

(如果我删除RuleFor(o => o.Sub.SubDataVal).GreaterThan(0);行,那么它可以工作!)

同样,如果我尝试对实际的子类进行单元测试:

    [Test]
    public void Should_have_error_when_sub_dataVal_is_zero()
    {
        validator = new TestModelValidator();
        validator.ShouldHaveValidationErrorFor(model => model.Sub.SubDataVal, 0);
    }

我收到“System.Reflection.TargetException:对象与目标类型不匹配”。来自FluentValidation.TestHelper.ValidatorTester`2.ValidateError(T instanceToValidate)

4

3 回答 3

9

您可以对模型和子模型进行单元测试,但您需要更改验证类以使用单独的验证器类来验证子模型:

public class TestModelValidator : AbstractValidator<TestModel>
{
    public TestModelValidator()
    {
        RuleFor(o => o.ParentVal).GreaterThan(0);
        RuleFor(o => o.Sub).SetValidator(new SubDataValidator());
    }
}

public class SubDataValidator : AbstractValidator<SubData>
{
    public SubDataValidator()
    {
        RuleFor(o => o.SubDataVal).GreaterThan(0);
    }
}

然后,您可以编写单元测试来测试每个验证器或同时测试两者。

于 2012-12-23T17:11:49.217 回答
6

我得出的结论是,对于这个 ShouldHaveValidationErrorFor 只是无法处理子类,所以不得不手动进行。IE

    [Test]
    public void Should_have_error_when_val_is_zero()
    {
        validator = new TestModelValidator();
        TestModel testRequest = new TestModel();
        //populate with dummy data
        var result = validator.Validate(testRequest);
        Assert.That(result.Errors.Any(o => o.PropertyName== "ParentVal"));
    }
于 2012-12-18T11:54:08.777 回答
2

使用 MSTest 和 FluentAssertions,您可以编写

[TestMethod]
public void Should_have_error_when_val_is_zero()
{
    // Given
    var validator = new TestModelValidator();
    var testModel = TestModel
    {
        ParentVal = 0
    }; // You should create a invalid TestModel object here

    // When
    validator.Validate(testModel).IsValid.Should().BeFalse();
}
于 2020-07-29T13:21:01.480 回答