简体   繁体   English

具有子/子类的类的单元测试 FluentValidation 规则

[英]Unit testing FluentValidation rules for classes with sub/child classes

Is it possible to write unit tests for fluentvalidation classes when the object we are validating has child classes that are also being validated.当我们正在验证的对象具有也正在验证的子类时,是否可以为 fluentvalidation 类编写单元测试。

As an example: My class looks like this例如:我的班级看起来像这样

public class TestModel
{

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

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

}

My validation logic looks like this:我的验证逻辑如下所示:

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

And when I write the following unit test当我编写以下单元测试时

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

I get a "System.NullReferenceException : Object reference not set to an instance of an object."我收到“System.NullReferenceException : Object reference not set to an instance of an object”。 exception from FluentValidation.TestHelper.ValidatorTester`2.ValidateError(T instanceToValidate) FluentValidation.TestHelper.ValidatorTester`2.ValidateError(T instanceToValidate) 中的异常

(if I remove the RuleFor(o => o.Sub.SubDataVal).GreaterThan(0); line, then it works!) (如果我删除RuleFor(o => o.Sub.SubDataVal).GreaterThan(0);行,那么它就起作用了!)

Similarly if I try and unit test the actual child class with:同样,如果我尝试对实际的子类进行单元测试:

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

I get a "System.Reflection.TargetException : Object does not match target type."我收到“System.Reflection.TargetException:对象与目标类型不匹配”。 from FluentValidation.TestHelper.ValidatorTester`2.ValidateError(T instanceToValidate)来自FluentValidation.TestHelper.ValidatorTester`2.ValidateError(T instanceToValidate)

You can unit test models and child models but you will need to change your validation class to use a separate validator class which just validates the child model:您可以对模型和子模型进行单元测试,但您需要更改验证类以使用单独的验证器类来验证子模型:

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);
    }
}

You can then write your unit tests to test each validator or both together.然后,您可以编写单元测试来测试每个验证器或同时测试两者。

I have come to the conclusion that for this ShouldHaveValidationErrorFor is just not capabable of dealing with subclasses, so have resorted to doing it manually.我得出的结论是,对于这个 ShouldHaveValidationErrorFor 无法处理子类,所以不得不手动进行。 ie 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"));
    }

With MSTest and FluentAssertions you can write使用 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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM