Moq + Unit Testing - System.Reflection.TargetParameterCountException: Parameter count mismatch
It's your Returns
clause. You have a 4 parameter method that you're setting up, but you're only using a 1 parameter lambda. I ran the following without issue:
[TestMethod]
public void IValueConverter()
{
var myStub = new Mock<IValueConverter>();
myStub.Setup(conv => conv.Convert(It.IsAny<object>(), It.IsAny<Type>(), It.IsAny<object>(), It.IsAny<CultureInfo>())).
Returns((object one, Type two, object three, CultureInfo four) => (int)one + 5);
var value = 5;
var expected = 10;
var actual = myStub.Object.Convert(value, null, null, null);
Assert.AreEqual<int>(expected, (int) actual);
}
No exceptions, test passed.
Moq + Unit Testing + System.Reflection.TargetParameterCountException: Parameter Count mismatch
If you use an expression in your .Returns instead of a value, then that expression's parameters must match those of the method signature you are mocking.
For example, I found this in SetupApiClientForGetZones:
this.MockHubApiClient.Setup(x => x.GetAsync<IEnumerable<Zone>>(It.IsAny<string>(), It.IsAny<IDictionary<string, string>>()))
.Returns(
(string name) =>
{
return zone == null ? Task.FromResult<IEnumerable<Zone>>(null) : Task.Run(() => zone);
});
When really it should be:
this.MockHubApiClient.Setup(x => x.GetAsync<IEnumerable<Zone>>(It.IsAny<string>(), It.IsAny<IDictionary<string, string>>()))
.Returns<string, IDictionary<string, string>>(
(name, dict) =>
{
return zone == null ? Task.FromResult<IEnumerable<Zone>>(null) : Task.Run(() => zone);
});
Using C# Moq testing getting Parameter count mismatch?
It appears that inside of the Returns
method you are specifying a parameter called request
of type couponDetail[]
, yet the method itself takes the parameters of (orderLine[], orderHeader)
. The method that is passed into Returns
gets invoked with the actual parameters that are passed into your mocked method which will cause the ParameterCountMismatchException you are getting.
- You can pass in the literal object you want by mocking your return before mocking the function. Example below:
var coupondetails = new couponDetail[] {
new couponDetail
{
description = "75% off the original price",
value = 50
},
new couponDetail
{
description = "500 off the original price",
value = 20
}
};
var couponService = DependencyResolver.Resolve<Mock<ICouponWebServiceAdapter>>();
couponService
.Setup(a => a.checkCouponAvailability(It.IsAny<orderLine[]>(), It.IsAny<orderHeader>()))
.Returns(coupondetails);
- You can pass a method to returns which MUST take all of the arguments passed into the original method. Example below:
var couponService = DependencyResolver.Resolve<Mock<ICouponWebServiceAdapter>>();
couponService
.Setup(a => a.checkCouponAvailability(It.IsAny<orderLine[]>(), It.IsAny<orderHeader>()))
.Returns((orderLine[] arg1, orderHeader arg2) => {
return new couponDetail[] {
new couponDetail
{
description = "75% off the original price",
value = 50
},
new couponDetail
{
description = "500 off the original price",
value = 20
}
};
});
Moq Params TargetParameterCountException : Parameter count mismatch Exception
I think you've hit some limitations here with Moq. It doesn't handle expression parameters well because it can be passed expressions as values itself. There's no way for Moq to know what part of the expression is intended to be resolved and what is part of the signature.
Also, I can't remember how well Moq handles params xx[] but it's quite possible you have a combination of two problems here.
Are you able to create a class that exposes the set of expressions as a property? If so it might be possible to change the signature of AllIncluding and tell Moq to match on any instance of that class.
Update
At the time of answering this was a limitation but is now possible. See the answer by Oleksandr Lytvyn
Parameter count mismatch in Unit test
It looks like your .Returns()
method does not implement the correct signature when you are doing the setup (hence the 'mismatch' error).
The .Returns()
method has to take a lambda function which matches the Receive()
method signature. Then you have access to the parameters with which the mock object was called, which would usually determine the returned value.
Try this instead:
mockOrderManager.Setup(mr => mr.Receive(It.IsAny<List<TransactionVM>>(), It.IsAny<string()))
.Returns((List<TransactionVM> target, string status) =>
{
// update logic here...
// target.RoleID = transactionList.Count() + 1;
// transactionList.Add(target);
return "OrderReceived";
});
The bigger problem is that it looks like you are testing your mock, rather than your business object. Your test class is called OrderServiceTest
, but you never create an order service.
My advice for creating unit tests is to use the 'should' naming convention and a 'AAA' (Arrange, Act, Assert) layout. Here's an example loosely based on your question:
[TestMethod]
public void OrderService_ShouldReceiveOrder()
{
// Arrange
var mockOrderManager = new Mock<IOrderManager>();
mockOrderManager.Setup(It.IsAny<List<TransactionVM>>(), "Permanent")
.Returns("OrderReceived");
var orderService = new OrderService(mockOrderManager.Object);
orderService.AddOrder(new TransactionVM());
// Act
orderService.ProcessOrders();
// Assert
mockOrderManager.Verify(_ => _.Receive(It.IsAny<List<TransactionVM>>(),
"Permanent"));
}
I think this makes it very clear what you are testing, and what you expect your test to do.
Parameter mismatch exception even the parameter count is correct
You have GetParty(int param1, int param2, int param3)
with 3 parameters, but in Returns
call you are using only one. Change it to something like this
.Returns((int i, int j, int k) => organizationList.Where(x => x.partyID == i).Single());
Related Topics
Newtonsoft.JSON Assembly Package Version Mismatch
How to Check If an Ip Address Is Within a Particular Subnet
Why Visual Studio Doesn't Create a Public Class by Default
Using Folderbrowserdialog in Wpf Application
Broadcastblock with Guaranteed Delivery in Tpl Dataflow
How to Use Dependency Injection in a .Net Core Actionfilterattribute
Combine Two Linq Lambda Expressions
What's the Best Way to Compare Double and Int
Why Is Modulus Operator Not Working for Double in C#
Extension Method on Enumeration, Not Instance of Enumeration
How to Create a Generic Class from a String in C#
How to Generate a 3-D Surface from Isolines
How to Get Character for a Given Ascii Value
How to Cast a Generic Enum to Int