如何unit testing简单属性有validation器设置?

我对多个模型对象中的某些属性有类似的规则,我想用自定义属性validation器替换它们,以避免unit testing中的代码重复。

我有我的财产validation人:

public class IntIdPropertyValidator: PropertyValidator { public IntIdPropertyValidator() : base("Property {PropertyName} should be greater than 0") { } protected override bool IsValid(PropertyValidatorContext context) { var value = (int)context.PropertyValue; return value > 0; } } 

并在模型validation器类中连接它:

 public class SomeRequestValidator : AbstractValidator { public SomeRequestValidator() { RuleFor(x => x.Id).SetValidator(new IntIdPropertyValidator()); } } 

试图测试:

 [Test] public void Validate_IdHasValidator_Success() { Init(); validator.ShouldHaveChildValidator(x => x.Id, typeof(IntIdPropertyValidator)); } 

但是测试总是失败。

那么,我如何测试实际为属性Id设置的validation器?

您正在以错误的方式使用ShouldHaveChildValidatorId是一种简单的类型。

ShouldHaveChildValidator正在复杂类型中使用。 (另见源代码 )

测试属性的正确方法是传递有效对象和无效对象,然后使用ShouldNotHaveValidationErrorFor和ShouldHaveValidationErrorFor进行变量 :

 [Test] public void Should_have_error_when_Id_Is_Ilegal() { validator.ShouldHaveValidationErrorFor(p => p.Id, new CreateWordRequest()); } [Test] public void Should_not_have_error_when_Id_Is_Legal() { validator.ShouldNotHaveValidationErrorFor(p => p.Id, new CreateWordRequest() { Id = 7 }); } 

编辑

以下代码将执行您要查找的validation:

 [Test] public void Validate_IdHasValidator_Success() { var validator = new SomeRequestValidator(); var descriptor = validator.CreateDescriptor(); var matchingValidators = descriptor.GetValidatorsForMember( Extensions.GetMember(x => x.Id).Name); Assert.That(matchingValidators.FirstOrDefault(), Is.InstanceOf()); } 

我想解释一下你不应该使用上述代码的原因。

当您使用UT类时,您将validation类行为是否不会受到损害。

创建自定义validation程序时,您将创建一个负责validation特定模型( – >业务规则)的类…

Id是一种简单类型,根据其父模型具有业务规则。 因此,您需要通过模型validation程序validationId的业务规则。

让我们假设你的一个模型突然需要改变。 在这种情况下,您没有任何validation任何现有业务规则不会受到损害(或者您决定在IntIdPropertyValidator进行更改,这样的移动会影响任何地方,即使您不想这样做)。

创建自定义Property Validator非常适合代码维护,但是测试应该针对模型validation器。

在复杂类型上,故事完全不同:

通常,复杂类型有自己的业务规则。 在这种情况下,您必须为它们创建自定义validation器,然后validation父validation器使用正确的validation器。 要validation的另一件事是:如果复杂类型是Null或复杂的规则,例如“当属性值为X然后复杂类型状态为Y”时……