Moq'ing Successive Calls to a Method

I just ran into a little problem when using Moq - I wanted to be able to mock up the result of a method call, but return a different result each time the mocked method was called (I'm pulling messages out of an MSMQ within a loop). Anyone who's used Moq will know that you usually mock results with the Setup() method - however, Moq has no built in way of achieving this (that I'm aware of).

To cut a long explanation short, I found a series of articles on Phil Haack's blog addressing (almost) the same issue. Phil's second post adds exception handling to his original example, but I wanted to return a "null", rather than throw an exception. Here's the code from Phil's blog, slightly rehashed to deal with nulls:

    public static class MoqExtensions {
        public static IReturnsResult<T> ReturnsInOrder<T, TResult>(this ISetup<T, TResult> setup,
            params object[] results) where T: class {
            var queue = new Queue(results);

            return setup.Returns(() => {
                var result = queue.Dequeue();
                if (result is Exception) {
                    throw result as Exception;
                }
                if (result == null) {
                    return default(TResult);
                }
                return (TResult)result;
            });
        }
    }

And here it is in use:

mockQueue
    .Setup(x => x.GetNextMessage())
    .ReturnsInOrder(new InputMessage(), new InputMessage(), new InputMessage(), null);

Thanks Phil.

Thil

UPDATE 28th Dec 2013


I've just been trying to append a callback to the above method using Moq's fluent notation - but I couldn't, as it returned void. I've modified the example above to return setup.Returns, allowing you to then chain notation as you would normally with Moq.

Popular posts from this blog

How I Learned to Lose Weight and Love Exercise (again)

GDPR: Application Password Security in 2018

AutoMapper: UseValue vs ResolveUsing vs MapFrom