我有一个非常有趣的行为。我有以下两个测试用例:
[Fact]
public void Ctor_WhenNeverIsTrueAndAfterOcurrenceIsNotNull_HasError()
{
// arrange
var reccurenceEnd = new RecurrenceEnd()
{
IsNever = true,
AfterOccurence = 1
};
// act
var validator = GetValidator();
// assert
validator.ShouldHaveValidationErrorFor(p => p.AfterOccurence, reccurenceEnd);
}
[Fact]
public void Ctor_WhenNeverIsFalseAndAfterOccurenceIsNullAndByDateIsNull_HasError()
{
// arrange
var reccurenceEnd = new RecurrenceEnd()
{
IsNever = false,
AfterOccurence = null,
ByDate = null
};
// act
var validator = GetValidator();
// assert
validator.ShouldHaveValidationErrorFor(p => p.AfterOccurence, reccurenceEnd);
}
在我的验证器上,如果我满足以下条件,则第一个测试失败,第二个通过。如果我更改规则的顺序,则第一个测试通过,第二个失败。
RuleFor(dto => dto.AfterOccurence)
.Cascade(CascadeMode.StopOnFirstFailure)
.Null()
.When(p => p.IsNever == true)
.NotEmpty()
.When(p => p.IsNever == false && p.ByDate == null);
如果我将验证器更改为以下内容,则两个测试均会通过。
RuleFor(dto => dto.AfterOccurence)
.Null()
.When(p => p.IsNever);
RuleFor(dto => dto.AfterOccurence)
.NotEmpty()
.When(p => p.IsNever == false && p.ByDate == null);
我设置错了吗?
答案 0 :(得分:2)
好的,从FluentValidation的github-issues得到了答案:
您好,这与您使用When条件有关。默认情况下,“条件”条件适用于同一RuleFor调用中的所有以前的验证器,因此,当您使用一次对RuleFor的调用时,实际上是在使条件加倍。 您应该使用对RuleFor的单独调用(如您在第二个示例中那样),或者使用“ When”的另一个重载,该重载允许您指定ApplyConditionTo.CurrentValidator
第二种解决方法是:
RuleFor(dto => dto.AfterOccurence)
.Cascade(CascadeMode.StopOnFirstFailure)
.Null()
.When(p => p.IsNever == true)
.NotEmpty()
.When(p => p.IsNever == false && p.ByDate == null, ApplyConditionTo.CurrentValidator);