4

私は流暢な検証を使用してモデルの検証を行っています。いくつかのネストされたクラスまたはクラスのコレクションを持つクラスがあり、それぞれに独自の IValidator があります。最初は、ネストされたバリデーターをセットアップするために次のようなことをしていました。

RuleFor(foo => foo.Header).SetValidator(new FooHeaderValidator());

これは非常にうまく機能します。

ネストされたバリデーターをさらに実装し始めると、トップレベルの検証に対する単体テストがいかに脆弱であるかに気づき始めました。基本的に、子バリデータを変更すると、予期しない動作が発生し、テストが失敗する可能性があります。明らかに、これは子バリデーターを直接インスタンス化したためです。私は今、コンストラクター注入を介してその依存関係を取り入れています。これにより、をモックできますFooHeaderValidator

null reference流暢な検証のどこかから来る例外で失敗するテストがあります。私のモックが提供していない何かがどこかで求められているとしか思えません。これは fluentvalidation からのスタック トレースです。

   at FluentValidation.Validators.ChildValidatorAdaptor.Validate(PropertyValidatorContext context)
   at FluentValidation.Validators.DelegatingValidator.Validate(PropertyValidatorContext context)
   at FluentValidation.Internal.PropertyRule.InvokePropertyValidator(ValidationContext context, IPropertyValidator validator, String propertyName)
   at FluentValidation.Internal.PropertyRule.<Validate>d__8.MoveNext()
   at System.Linq.Enumerable.<SelectManyIterator>d__14`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList(IEnumerable`1 source)
   at FluentValidation.AbstractValidator`1.Validate(ValidationContext`1 context)
   at FluentValidation.AbstractValidator`1.Validate(T instance)

これまでに誰かがこれに遭遇し、私が欠けているものを知っていますか? これらのバリデーターを嘲笑することに私は夢中になっていますか?

4

3 に答える 3

6

したがって、これは実際には簡単です。Validate答えは、を受け入れるオーバーライド用にモックを設定する必要があるということですValidationContext<T>。RhinoMocks では次のようになります。

public static IValidator<T> GetMockedNestedValidator<T>()
{
    var mockedValidator = MockRepository.GenerateMock<IValidator<T>>();
    abstractValidator.Stub(x => x.Validate(Arg<ValidationContext<T>>.Is.Anything)).Return(new ValidationResult());
    return mockedValidator;
}

Moq を使用すると、かなり似ています。

public static Mock<IValidator<T>> GetMockedNestedValidator<T>()
{
    var mockedValidator = new Mock<IValidator<T>>();
    abstractValidator.Setup(x => x.Validate(Arg<ValidationContext<T>>.Is.Anything)).Returns(new ValidationResult());
    return mockedValidator;
}
于 2013-03-18T22:11:47.033 に答える
0

非同期検証を使用して同じ質問がある人のために、これに追加するだけです。以下をオーバーライドする必要がありました(NSubstituteを使用)

validator.ValidateAsync(Arg.Any<ValidationContext>(), Arg.Any<CancellationToken>()).Returns(Task.FromResult(new ValidationResult()));

注:私の場合、非ジェネリックの ValidationContext をオーバーライドする必要がありました

于 2016-06-07T10:14:38.390 に答える