如何单元测试简单 属性 有验证器集?
How to unit test simple property has validator set?
我对多个模型对象中的某些属性有类似的规则,我想用自定义 属性 验证器替换它们以避免单元测试中的代码重复。
我有我的 属性 验证器:
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;
}
}
并在模型验证器中连接它 class:
public class SomeRequestValidator : AbstractValidator<CreateWordRequest>
{
public SomeRequestValidator()
{
RuleFor(x => x.Id).SetValidator(new IntIdPropertyValidator());
}
}
尝试测试:
[Test]
public void Validate_IdHasValidator_Success()
{
Init();
validator.ShouldHaveChildValidator(x => x.Id, typeof(IntIdPropertyValidator));
}
但是测试总是失败。
那么,我如何测试验证器实际上是为 属性 ID 设置的?
您使用 ShouldHaveChildValidator
的方式有误。 Id
是简单类型。
ShouldHaveChildValidator is being in used on complex types. (see also the source code)
测试属性的正确方法是传递有效对象和无效对象,然后使用ShouldNotHaveValidationErrorFor and 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
});
}
编辑
以下代码将执行您正在寻找的验证:
[Test]
public void Validate_IdHasValidator_Success()
{
var validator = new SomeRequestValidator();
var descriptor = validator.CreateDescriptor();
var matchingValidators = descriptor.GetValidatorsForMember(
Extensions.GetMember<CreateWordRequest, int>(x => x.Id).Name);
Assert.That(matchingValidators.FirstOrDefault(), Is.InstanceOf<IntIdPropertyValidator>());
}
我想向您解释一下您不应该使用上述代码的原因。
当您 UT class 时,您确认 class 行为不会受到伤害。
创建自定义验证器时,您创建了一个 class 负责验证特定模型( --> 业务规则)...
Id
是一个简单类型,根据其父模型具有业务规则。
因此需要通过模型验证器验证Id
的业务规则。
假设您的其中一个模型突然需要更改。在这种情况下,您没有任何验证可以证明您现有的任何业务规则都不会受到损害(或者您决定在 IntIdPropertyValidator
内进行更改,这样的举动将影响任何地方,即使您不想).
创建自定义 Property Validator
对于代码维护非常有用,但是,测试应该针对模型验证器。
对于复杂类型,情况就完全不同了:
通常复杂类型都有自己的业务规则。在这种情况下,您必须为它们创建自定义验证器,然后验证父验证器是否使用了正确的验证器。另外要验证的是:如果复杂类型是Null
或者复杂规则如"when the property value is X and then complex type state is Y"...
我对多个模型对象中的某些属性有类似的规则,我想用自定义 属性 验证器替换它们以避免单元测试中的代码重复。
我有我的 属性 验证器:
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;
}
}
并在模型验证器中连接它 class:
public class SomeRequestValidator : AbstractValidator<CreateWordRequest>
{
public SomeRequestValidator()
{
RuleFor(x => x.Id).SetValidator(new IntIdPropertyValidator());
}
}
尝试测试:
[Test]
public void Validate_IdHasValidator_Success()
{
Init();
validator.ShouldHaveChildValidator(x => x.Id, typeof(IntIdPropertyValidator));
}
但是测试总是失败。
那么,我如何测试验证器实际上是为 属性 ID 设置的?
您使用 ShouldHaveChildValidator
的方式有误。 Id
是简单类型。
ShouldHaveChildValidator is being in used on complex types. (see also the source code)
测试属性的正确方法是传递有效对象和无效对象,然后使用ShouldNotHaveValidationErrorFor and 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
});
}
编辑
以下代码将执行您正在寻找的验证:
[Test]
public void Validate_IdHasValidator_Success()
{
var validator = new SomeRequestValidator();
var descriptor = validator.CreateDescriptor();
var matchingValidators = descriptor.GetValidatorsForMember(
Extensions.GetMember<CreateWordRequest, int>(x => x.Id).Name);
Assert.That(matchingValidators.FirstOrDefault(), Is.InstanceOf<IntIdPropertyValidator>());
}
我想向您解释一下您不应该使用上述代码的原因。
当您 UT class 时,您确认 class 行为不会受到伤害。
创建自定义验证器时,您创建了一个 class 负责验证特定模型( --> 业务规则)...
Id
是一个简单类型,根据其父模型具有业务规则。
因此需要通过模型验证器验证Id
的业务规则。
假设您的其中一个模型突然需要更改。在这种情况下,您没有任何验证可以证明您现有的任何业务规则都不会受到损害(或者您决定在 IntIdPropertyValidator
内进行更改,这样的举动将影响任何地方,即使您不想).
创建自定义 Property Validator
对于代码维护非常有用,但是,测试应该针对模型验证器。
对于复杂类型,情况就完全不同了:
通常复杂类型都有自己的业务规则。在这种情况下,您必须为它们创建自定义验证器,然后验证父验证器是否使用了正确的验证器。另外要验证的是:如果复杂类型是Null
或者复杂规则如"when the property value is X and then complex type state is Y"...