问题
I have this method:
public void Valida(Validazione.IValidator<MyType> validator)
{
// do something...
Validazione.IMapper<MyType> mapper = new MyTypeMapper();
ValidationResult result = validator.Validate(myTypeObj, mapper, new ValidationConfiguration());
// ...continue doing something else
}
that I want to unit test, so I would mock (using Moq framework) validator
to steer the result of Validate
method, so I wrote this unit test:
[TestMethod]
public void Long_test_name_as_best_practice()
{
// arrange
MyAggregateRoot aggregateRoot = AggregateRoot.Stub();
var mockedValidator = new Mock<Validazione.IValidator<MyType>>();
mockedValidator.Setup(a => a.Validate(
It.Is<MyType>(x => x.Id == Guid.Parse("3F2504E0-4F89-11D3-9A0C-0305E82C3301")),
It.IsAny<Validazione.IMapper<MyType>>(),
It.IsAny<ValidationConfiguration>()
)).Returns<Validazione.ValidationResult>(x => x = It.IsAny<Validazione.ValidationResult>());
// act
aggregateRoot.Valida(mockedValidator.Object);
// Assert (now showed for readability sake)
}
It builds, it sounds me pretty correct but in the end I get:
An exception of type 'System.Reflection.TargetParameterCountException' occurred in mscorlib.dll but was not handled in user code Additional information: Parameter count mismatch
I google around but I can't understand the reason. To me seems Ok.
Edit after comment(s)
This is the stack trace of the exception:
in System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
in System.Reflection.RuntimeMethodInfo.UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
in System.Delegate.DynamicInvokeImpl(Object[] args)
in System.Delegate.DynamicInvoke(Object[] args)
in Moq.Extensions.InvokePreserveStack(Delegate del, Object[] args)
in Moq.MethodCallReturn`2.Execute(ICallContext call)
in Moq.ExecuteCall.HandleIntercept(ICallContext invocation, InterceptorContext ctx, CurrentInterceptContext localctx)
in Moq.Interceptor.Intercept(ICallContext invocation)
in Moq.Proxy.CastleProxyFactory.Interceptor.Intercept(IInvocation invocation)
in Castle.DynamicProxy.AbstractInvocation.Proceed()
in Castle.Proxies.IValidator`1Proxy.Validate(MyType myTypeObj, IMapper`1 mapper, ValidationConfiguration configuration)
in MyNamespace.Valida(IValidator`1 validator) in c:\Sviluppo\ProjectName\Main\src\Project.MySubProject.Domain\filename.cs:riga 104
in MyTestNamespace.Long_test_name_as_best_practice() in c:\Sviluppo\ProjectName\Main\src\Project.SubProject.Domain.Tests\Test_AggregateCommand.cs:riga 103
回答1:
In the Returns
clause of this Setup
statement:
mockedValidator.Setup(a => a.Validate(
It.Is<MyType>(x => x.Id == Guid.Parse("3F2504E0-4F89-11D3-9A0C-0305E82C3301")),
It.IsAny<Validazione.IMapper<MyType>>(),
It.IsAny<ValidationConfiguration>()
)).Returns<Validazione.ValidationResult>(x => x = It.IsAny<Validazione.ValidationResult>());
It looks like you don't care what this method returns. But you're giving the Returns
statement a Func<ValidationResult.ValidationResult>
. This is where your exception is coming from.
This syntax is intended to allow you to compute a return value based on the inputs to the method being setup (here it's Validate
), and so you're supposed to pass in a Func
with the same arguments as the method being setup. Since your method has 3 arguments and you give Returns
a function that takes 1, there's an argument mismatch.
If you want to just return any ValidationResult
, do this instead:
.Returns(It.IsAny<Validazione.ValidationResult>())
If you actually do want to compute a ValidationResult
based on arguments to Validate
, do this:
.Returns<MyType, Validazione.IMapper<MyType>, ValidationConfiguration>
((m,t,c) => /* TODO: compute a ValidationResult */ )
来源:https://stackoverflow.com/questions/26906718/parameter-count-mismatch-in-a-mocked-method-call