Moq + Unit Testing - System.Reflection.TargetParameterCountException: Parameter count mismatch

32,508

Solution 1

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.

Solution 2

Not an answer for OP but perhaps for future googlers:

I had a Callback that didn't match the signature of the method being setup

Mock
    .Setup(r => r.GetNextCustomerNumber(It.IsAny<int>()))
    .Returns(AccountCounter++)
    .Callback<string, int>(badStringParam, leadingDigit =>
    {
        // Doing stuff here, note that the 'GetNextCustomerNumber' signature is a single int 
        // but the callback unreasonably expects an additional string parameter.
    });

This was the result of some refactoring and the refactoring tool of course couldn't realise that the Callback signature was incorrect

Solution 3

Perhaps it's because you are passing null but It.IsAny<Object>() is expecting any object except null? What happens if you do the following?:

var actual = mock.Object.Convert(value, new object(), typeof(object), CultureInfo.CurrentCulture);

This is just a stab in the dark from me, I'm more familiar with Rhino.Mocks.


My 2nd guess:

Having looked at the Moq.chm that comes with the download,

You are using the Setup(Expression<Action<T>>) method which "Specifies a setup on the mocked type for a call to a void method."

You want te Setup<TResult>(Expression<Func<T,TResult>>) method that "Specifies a setup on the mocked type for a call to a value returning method".

So you could try:

mock.Setup<Int32>(
    conv => {
        conv.Convert(
            It.IsAny<Object>(), 
            It.IsAny<Type>(),
            It.IsAny<Object>(), 
            It.IsAny<CultureInfo>());
        return  num + 5;
        });

Solution 4

In my case, I thought that the type in Returns<> is the output type, but in fact it was the input type(s).

So if you have a method

public virtual string Foo(int a, int b) { ... }

The correct clause is .Returns<int, int>(...), NOT .Returns<string>(...) which is what I thought initially.

My mistake was because I was testing a function with the same input and return type initially - for example public virtual string Foo(string a).

Share:
32,508
myermian
Author by

myermian

Updated on July 05, 2022

Comments

  • myermian
    myermian almost 2 years

    I'm tring to use a lambda with a multiple-params function but Moq throws this exception at runtime when I attempt to call the mock.Object.Convert(value, null, null, null); line.

    System.Reflection.TargetParameterCountException: Parameter count mismatch

    The code is:

    var mock = new Mock<IValueConverter>();
    
    mock.Setup(conv => conv.Convert(It.IsAny<Object>(), It.IsAny<Type>(),
        It.IsAny<Object>(), It.IsAny<CultureInfo>())).Returns((Int32 num) => num + 5);
    
    var value = 5;
    var expected = 10;
    var actual = mock.Object.Convert(value, null, null, null);
    

    What is the proper way to implement it?

  • myermian
    myermian over 12 years
    mock.Setup<TResult> infers the return type as Object because the Convert method returns an Object.
  • Erik Dietrich
    Erik Dietrich over 12 years
    I was going to inquire as to whether this was a test of the framework or not, but I figured I'd give the benefit of the doubt that perhaps it was interim code to try getting the Mock to behave properly.
  • Ritch Melton
    Ritch Melton over 12 years
    I assume it is too, but it made me chuckle anyway.
  • Erik Dietrich
    Erik Dietrich over 12 years
    I hear ya. When I executed the code, I thought "yup, framework libraries still working." :)
  • dblood
    dblood almost 7 years
    wow, I was banging my head against this same issue and get kept glossing right over the callback until I read your post. Hugely helpful and I'm glad you posted it.
  • Pete
    Pete about 5 years
    This was my issue as well. I added a parameter to a method, fixed the Setup() call, but missed the Callback() parameter.