Parameter count mismatch error

665 views
Skip to first unread message

TrueWill

unread,
Jul 12, 2011, 6:27:42 PM7/12/11
to Moq Discussions
This isn't a bug, just a VERY unintuitive error from Moq or Castle.
Would there be a way to disallow method groups or provide a clearer
error message in this case?

Basically the poster wrote

.Returns(coaDepartments.AsQueryable)

when he meant

.Returns(coaDepartments.AsQueryable())

http://stackoverflow.com/questions/6671703/how-do-i-resolve-this-moq-error-system-reflection-targetparametercountexception/6671880

Daniel Cazzulino

unread,
Jul 12, 2011, 9:58:22 PM7/12/11
to moq...@googlegroups.com

We have no way of telling apart a true delegate return value, which is quite valid, from this scenario :(

/kzu from Android

On Jul 12, 2011 7:27 PM, "TrueWill" <bi...@truewill.net> wrote:

TrueWill

unread,
Jul 12, 2011, 10:10:28 PM7/12/11
to Moq Discussions
Understood. Thanks!

On Jul 12, 8:58 pm, Daniel Cazzulino <k...@clariusconsulting.net>
wrote:
> We have no way of telling apart a true delegate return value, which is quite
> valid, from this scenario :(
>
> /kzu from Android
> On Jul 12, 2011 7:27 PM, "TrueWill" <b...@truewill.net> wrote:

Kenneth Xu

unread,
Jul 12, 2011, 11:47:38 PM7/12/11
to moq...@googlegroups.com
Coincidentally, I just finished reading the section "Use overloading judiciously" in a book, below is the exact quote:

"If the typical user of an API does not know which of several method overloadings will get invoked for a given set of parameters, use of the API is likely to result in errors. These errors will likely manifest themselves as erratic behavior at runtime, and many programmers will be unable to diagnose them. Therefore you should avoid confusing uses of overloading. Exactly what constitutes a confusing use of overloading is open to some debate. A safe, conservative policy is never to export two overloadings with the same number of parameters."

I have made exactly the same mistake as the stackoverflow's questioner before. Although I learnt how to interpret the error message now, I felt it would be much helpful if the method takes delegates was named as "Does" instead of overloaded "Returns".

Cheers,
Kenneth

Daniel Cazzulino

unread,
Jul 12, 2011, 11:53:09 PM7/12/11
to moq...@googlegroups.com
Returning a delegate from a member is not the same as "doing" the delegate:

public Func<Type, string> TypeNameFormatter { get; set; }

// this is valid
mock.Setup(x => x.TypeNameFormatter).Returns(myFormatter.SimpleTypeName);
// this too 
mock.Setup(x => x.TypeNameFormatter).Returns(type => type.FullName);

// this too 
Func<Type, string> formatter = type => type.FullName;
mock.Setup(x => x.TypeNameFormatter).Returns(formatter);


accessing the property does NOT invoke the delegate, it does nothing:

var formatter = mock.Object.TypeNameFormatter;

Assert.NotNull(formatter);


/kzu

--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


Kenneth Xu

unread,
Jul 13, 2011, 12:41:43 AM7/13/11
to moq...@googlegroups.com
hmm... the user was actually calling the first of below overloaded Returns by mistake.

IReturnsResult<TMock> Returns(Func<TResult> valueFunction)
IReturnsResult<TMock> Returns(TResult value)

My test shows Moq actually executes the delegate, not returning the delegate, which won't be type compatible.

        public interface IA
        {
            string MakeString();
        }

        public static void MoqReturns()
        {
            var mock = new Mock<IA>();
            mock.Setup(x => x.MakeString()).Returns(ReturnSomeString);
            Assert.AreEqual("SomeString", mock.Object.MakeString());
        }

        private static string ReturnSomeString()
        {
            return "SomeString";
        }

Cheers,
Kenneth

Daniel Cazzulino

unread,
Jul 13, 2011, 1:54:00 AM7/13/11
to moq...@googlegroups.com
that's different. that overload receives a delegate for calculating the value to return on the fly. The property itself is not of a delegate type, which is the other scenario we were discussing.

vNext that overload should be called ReturnsLazy or something, to avoid confusions... 


/kzu

--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


Kenneth Xu

unread,
Jul 13, 2011, 9:39:27 AM7/13/11
to moq...@googlegroups.com
Yes, that's exactly what I meant in my original post, sorry if I didn't make it clear.

Be it "Does", "ReturnLazy" or something else, as long as we don't overload the name "Returns", we can avoid the confusion.

Cheers,
Kenneth

Ian Griffiths

unread,
Jul 15, 2011, 8:31:04 AM7/15/11
to moq...@googlegroups.com
I've always found this overloading for two quite different styles of setup to be unsatisfactory. (Even when it doesn't actually cause problems.) They're not quite the same thing, so it seems odd to give them the same name.
 
One way to look at the distinction is as "Returns a value calculated during setup" vs. "Returns whatever value that this callback returns at invocation time". I'm not convinced that either of them should be called just Returns.
 
So for the non-callback flavour, would ReturnsValue be a more descriptive name? I'm not sure what to call the other flavour. ReturnsLazy could work, although I don't love it. ReturnsDeferred? ReturnsViaCallback? ReturnsCalculated? Or maybe the two forms could be called ReturnsFixedValue and ReturnsCalculatedValue.
 
It would even be possible to "fluentize" it some more, e.g. Returns().Value(xx) and Returns().UsingCallback(yy), although I don't particularly like that.
 
 
IanG

Daniel Cazzulino

unread,
Jul 15, 2011, 9:59:43 AM7/15/11
to moq...@googlegroups.com

Agreed. Also, I don't like long methods names much...

/kzu from Android

On Jul 15, 2011 9:31 AM, "Ian Griffiths" <ian.gr...@gmail.com> wrote:

Kenneth Xu

unread,
Jul 15, 2011, 3:23:59 PM7/15/11
to moq...@googlegroups.com
I see later more as "Use the delegate as the mock implementation of this method/property". In fact,may folds asked me how to provided a mock method implementation using Moq. The answer is now "Returns"

How about

mock.Setup(x=>x.Method1(arg)).As(Func<T, TResult> action);

Short and to the point.

Kenneth Xu

unread,
Jul 15, 2011, 3:26:23 PM7/15/11
to moq...@googlegroups.com
I meant: ...many folks asked me how to provide... (sorry on a tiny keyboard:)

On Fri, Jul 15, 2011 at 3:23 PM, Kenneth Xu <ken...@homexu.com> wrote:
...may folds asked me how to provided...

Daniel Cazzulino

unread,
Jul 15, 2011, 4:19:55 PM7/15/11
to moq...@googlegroups.com
I like the "shortness". Not sure a newbie would know what "As" means in this context, cast the setup to a func? just one more fluent method they are supposed to dot into?

.CalculatedBy(Func<....>)

?

And the other .Returns is fine I think.

ReturnsCalculated?


/kzu

--
Daniel Cazzulino | Developer Lead | XML MVP | Clarius Consulting | +1 425.329.3471


John Thornborrow

unread,
Jul 15, 2011, 5:01:18 PM7/15/11
to moq...@googlegroups.com
Calculate(x => x)

or

Return(value)

Daniel Cazzulino

unread,
Jul 16, 2011, 12:01:24 AM7/16/11
to moq...@googlegroups.com

+1!

/kzu from mobile

Reply all
Reply to author
Forward
0 new messages