4

FluentValidation.TestHelper 名前空間の拡張メソッド .ShouldHaveChildValidator() には、モデルを取るオーバーロードがありません。次に、次の例のように When() 句を使用するときに、子バリデータが正しく設定されていることをテストするにはどうすればよいですか?

例えば

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() 条件を考慮していません。

.ShouldHaveValidationErrorFor() などの FluentValidation.TestHelper 名前空間の他のメソッドには、モデルを受け取るオーバーロードがあることに気付きました。そのため、前提条件を満たすモデルを設定することで、When() 句を使用して単純なプロパティ タイプを簡単にテストできます。

何か案は?

4

2 に答える 2

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");
}
于 2012-12-20T09:51:06.707 に答える
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");
}
于 2015-04-08T17:35:06.087 に答える