This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.


Queuing Moq Return Values

Some testing scenarios require that a dependency's methods are called repeatedly. When the dependency is mocked using the Moq framework, these calls can be configured with expectations to return different results each time.

Moq and Func Delegates

When you are unit testing code that has dependencies, you may decide to replace those dependencies with mock objects in order that you can isolate the code under test. In some situations, a single method of a mock object may be called multiple times by the code being tested. If the result of each call should be different, it is useful to be able to create a queue of return values and return the next item from the queue with each call.

Moq allows you to create expectations and specify a return value directly. This value is returned for each call that matches the expectation. To support more complex scenarios, Moq also allows you to provide a Func delegate to the Returns method. Instead of returning the delegate, the function is executed each time the expectation is met and the result of the delegate is returned.

We can take advantage of this functionality by populating a queue with return values and creating a lambda expression that dequeues and returns values. We can demonstrate this by creating an interface to mock:

public interface ITestObject
    int GetResult();

We can now create a mock object for the interface:

Mock<ITestObject> mockTestObject = new Mock<ITestObject>();

Next we can create a queue of values that we wish the test double to return:

Queue<int> results = new Queue<int>(new int[] { 1, 2, 4 });

Finally we need to set up our expectation and provide the lambda expression that will extract the next value from the queue and return it:

mockTestObject.Setup(m => m.GetResult()).Returns(() => results.Dequeue());

When the mock object's GetResult method is first called, the returned value will be 1. The second call will return 2 and the third 4. A fourth call will throw an exception as the queue is exhausted.

6 June 2011