nat*_*lez 3 .net tdd mocking fluentvalidation
我正在使用fluentvalidation进行模型验证.我有一个类,有几个嵌套类或类集合,每个类都有自己的IValidator.最初我正在做这样的事情来设置嵌套的验证器:
RuleFor(foo => foo.Header).SetValidator(new FooHeaderValidator());
Run Code Online (Sandbox Code Playgroud)
这非常有效.
当我开始实现更多的嵌套验证器时,我开始意识到我的单元测试对于顶级验证是多么脆弱.基本上,对子验证器的任何更改都可能导致意外行为并导致测试失败.显然这是由于我直接实例化了子验证器.我现在正在通过构造函数注入获取该依赖项.这让我嘲笑了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)
Run Code Online (Sandbox Code Playgroud)
有没有人遇到这个,知道我错过了什么?我是否因为嘲笑这些验证器而疯狂?
所以这实际上很简单.答案是你需要为Validate接受a 的覆盖设置你的模拟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;
}
Run Code Online (Sandbox Code Playgroud)
与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;
}
Run Code Online (Sandbox Code Playgroud)