如何对具有验证程序集的简单属性进行单元测试

本文关键字:属性 简单 单元测试 程序集 验证 | 更新日期: 2023-09-27 18:00:09

我对多个模型对象中的一些属性有类似的规则,我想用自定义属性验证器来替换它们,以避免单元测试中的代码重复。

我有我的财产验证器:

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;
    }
}

并将其连接到模型验证器类中:

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的方式不对。CCD_ 2是一个简单类型。

ShouldHaveChildValidator正在复杂类型上使用。(另请参阅源代码)

测试属性的正确方法是传递有效对象和无效对象,然后使用ShouldNotHaveValidationErrorFor和ShouldHaveValidation ErrorFor进行更改:

[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类时,您验证类行为不会受到损害。

当您创建自定义验证器时,您将创建一个负责验证特定模型(-->业务规则)的类。。。

Id是一个简单类型,根据其父模型具有业务规则。因此,您需要通过模型验证器来验证Id的业务规则。

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

创建一个自定义Property Validator对于代码维护非常好,但是,测试应该针对模型验证器。

在复杂类型上,情况大不相同:

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