FluentValidation.TestHelper命名空间中的扩展方法.ShouldHaveChildValidator()没有获取模型的重载。在使用如下例中的When()子句时,如何测试子验证器是否设置正确?
E.g。
public class ParentModel
{
public bool SomeCheckbox { get; set; }
public ChildModel SomeProperty { get; set; }
}
public class ParentModelValidator : AbstractValidator<ParentModel>
{
RuleFor(m => m.SomeProperty)
.SetValidator(new ChildModelValidator())
.When(m => m.SomeCheckbox);
}
我想断言,如果SomeCheckbox为true,则存在子验证器,如果SomeCheckbox为false,则子验证器不存在。
到目前为止,我在单元测试中有以下内容:
ParentModelValidator validator = new ParentModelValidator();
validator.ShouldHaveChildValidator(
m => m.SomeProperty,
typeof(ChildModelValidator));
但是没有考虑.When()条件。
我注意到FluentValidation.TestHelper命名空间中的其他方法(如.ShouldHaveValidationErrorFor())有一个带模型的重载,因此通过设置满足该模型的模型,可以很容易地测试带有When()子句的简单属性类型。先决条件。
有什么想法吗?
答案 0 :(得分:2)
以下是我如何实现这一目标的片段:
public class ParentModelSimpleValidator : AbstractValidator<ParentModel>
{
public ParentModelSimpleValidator()
{
When(x => x.HasChild, () =>
RuleFor(x => x.Child)
.SetValidator(new ChildModelSimpleValidator()));
}
}
public class ChildModelSimpleValidator : AbstractValidator<ChildModel>
{
public ChildModelSimpleValidator()
{
RuleFor(x => x.ChildName)
.NotEmpty()
.WithMessage("Whatever");
}
}
以下是相关的简化模型:
[Validator(typeof(ParentModelSimpleValidator))]
public class ParentModel
{
public bool HasChild { get { return Child != null; } }
public ChildModel Child { get; set; }
}
[Validator(typeof(ChildModelSimpleValidator))]
public class ChildModel
{
public string ChildName { get; set; }
public int? ChildAge { get; set; }
}
这是一个样本单元测试:
[TestMethod]
public void ShouldValidateChildIfParentHasChild()
{
var validator = new ParentModelSimpleValidator();
var model = new ParentModel
{
ParentName = "AABBC",
Child = new ChildModel { ChildName = string.Empty }
};
validator.ShouldHaveErrorMessage(model, "Whatever");
}
答案 1 :(得分:1)
这里游戏很晚,但我刚开始使用FluentValidation
,那是我的解决方案
public class ParentValidator: AbstractValidator<ParentModel>
{
public ParentValidator()
{
// other rules here
// use == for bool?
When(model => model.SomeBoolProperty == false, () => RuleFor(model => model.ChildClass).SetValidator(new ChildClassValidator()));
}
}
public class ChildClassValidator: AbstractValidator<ChildClass>
{
public ChildClassValidator()
{
this
.RuleFor(model => model.SomeProperty).NotNull();
}
}
然后测试
[TestMethod]
public void ParentValidator_should_have_error_in_child_class_property_when_bool_is_false_on_parent()
{
// Arrange - API does not support typical unit test
var validator = new ParentValidator()
var foo = new ParentModel() { SomeBoolProperty = false };
foo.ChildClass.SomeProperty = null;
// Act
var result = validator.Validate(foo);
// Assert - using FluentAssertions
result.Errors.Should().Contain(err => err.PropertyName == "ChildClass.SomeProperty");
}