首页 > 解决方案 > Fluent TestValidate 不会为使用 SetValidator 在 List 上设置的规则引发验证错误

问题描述

在使用 Fluent 的测试助手 TestValidate 方法对我的规则进行单元测试时,当对象列表为空时,它会抛出 TestValidationException。验证器设置指定NotNull规则。

验证器如下所示

public class RequestValidator : AbstractValidator<Request>
{
    public RulebookRequestValidator()
    {
        RuleFor(x => x.Id).NotEmpty();
        RuleFor(x => x.Name).NotEmpty();
        RuleForEach(x => x.EntryRequests).SetValidator(new EntryRequestValidator()).NotNull(); // Would like to validate this rule when EntryRequests is null.
    }
}

子验证器看起来像这样,

public class EntryRequestValidator : AbstractValidator<EntryRequest>
{
        public EntryRequestValidator()
        {
            RuleFor(x => x.EntryRequestId).NotEmpty();
            RuleForEach(x => x.Messages).NotNull().SetValidator(new MessagesValidator());
        }
 }

在我的单元测试中

[TestMethod]
public void Should_Have_Error_When_Object_Is_Empty()
{
    // arrange
    Request model = new () { EntryRequests = new () };
    var validator = new RequestValidator();

    // assert
    var result = validator.TestValidate(model);

    // act
    Assert.IsFalse(result.IsValid);
    result.ShouldHaveValidationErrorFor(x => x.Id)
            .WithErrorCode(NotEmptyValidatorErrorCode);
    result.ShouldHaveValidationErrorFor(x => x.Name)
            .WithErrorCode(NotEmptyValidatorErrorCode);
    result.ShouldHaveValidationErrorFor(x => x.EntryRequests); // throws ValidateTestException. 
 }

这是在单元测试列表中测试子验证器的正确方法吗?寻找一种方法来使用 TestValidate 对这个规则进行单元测试。

标签: c#unit-testing.net-coremstestfluentvalidation

解决方案


您的验证器工作正常,但有一个小问题。

让我们看看这个规则:

RuleForEach(x => x.EntryRequests).SetValidator(new EntryRequestValidator()).NotNull();

它基本上说:对集合中的每个元素运行 NotNull 检查(并执行 EntryRequestValidator)EntryRequest

它不起作用,因为您的收藏是的:EntryRequests = new ()。它没有元素,所以没有什么要验证的。

将其更改为:

RuleFor(x => x.EntryRequests).NotEmpty(); // throws validation error when collection is null or empty
RuleForEach(x => x.EntryRequests).SetValidator(new EntryRequestValidator()).NotNull(); 

使用上述规则,您将在以下情况下收到验证错误:

  • 入口请求 = 空
  • EntryRequests = 空列表
  • 此列表的任何元素为空

加上来自嵌套验证器的所有验证


推荐阅读