Mocking successive calls to a method - a neat trick

60 views
Skip to first unread message

mabster

unread,
Jun 2, 2008, 9:06:36 PM6/2/08
to MoQ Discussions
Here's a little snippet of code we're using to mock the
IDbCommand.CreateParameter() method so that each call returns a new
mocked IDbDataParameter. I was very happy with this and thought I'd
share it in case it helps someone else out there with a similar
problem.

var pq = new Queue<IDbDataParameter>(new[] { mockFirstParam.Object,
mockSecondParam.Object });

mockCommand.Expect(c => c.CreateParameter()).Returns(() =>
pq.Dequeue());


So we set up a queue containing our mocked parameter objects, and then
use the Dequeue() method so that each call to the CreateParameter()
method returns the next item in the queue.

I know that you guys are looking at some sort of "sequencing" feature
for Moq (which I think would be fantastic) but this is a good way to
mock successive results from a method in the meantime.

Matt

Daniel Cazzulino

unread,
Jun 3, 2008, 1:58:00 PM6/3/08
to moq...@googlegroups.com
very nice trick indeed!

Daniel Cazzulino

unread,
Mar 15, 2009, 10:25:13 PM3/15/09
to moq...@googlegroups.com
Here's another guy who took Matt's idea even further:

http://www.timvw.be/setup-expectation-with-successive-function-calls-using-moq/

should we include something like this built-in?
should we "revive" Moq.Contrib?

/kzu

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


On Mon, Jun 2, 2008 at 10:06 PM, mabster <mab...@madprops.org> wrote:

Matt Hamilton

unread,
Mar 15, 2009, 10:35:17 PM3/15/09
to moq...@googlegroups.com
I've left some comments on Tim's post but they're not approved yet so I'm not sure if others can see 'em.
 
Anyway, I think we could have two versions of this method (either in the core or in a contrib project):
 
public static IReturnsResult<TMock> ReturnsInOrder<TMock, TResult>(this ISetup<TMock, TResult> setup, params Func<TResult>[] valueFunctions) where TMock : class
 {
  var functionQueue = new Queue<Func<TResult>>(valueFunctions);
  return setup.Returns(() => functionQueue.Dequeue()());
 }
public static IReturnsResult<TMock> ReturnsInOrder<TMock, TResult>(this ISetup<TMock, TResult> setup, params TResult[] valuess) where TMock : class
 {
  var functionQueue = new Queue<TResult>(values);
  return setup.Returns(() => functionQueue.Dequeue()());
 }
In other words, a "lazy" one that takes an array of functions, and an "immediate" one that takes an array of TResult.
 
Also note that you can just pass the array directly into the Queue's constructor which saves a line of code and maybe some CLR instructions.
 
Matt
 
ps. This code wouldn't actually compile for me so I'm guessing it's for Moq 3.x (we're still using the older release). I've ported it to Moq 2.x too, if anyone's interested.
Reply all
Reply to author
Forward
0 new messages