Unit Test Stubs – Returning different values on consecutive calls

I have been learning C# these past few months.  The other day I had to write a unit test in C# that would return different results on consecutive calls from a mocked method where the inputs were the same.  With my Java background, I was familiar with how to do this with the Java mocking libraries such as JMock and Mockito.

For example, in JMock:

String someInput = "test input";
atLeast(1).of (myMockObject).myMethod(someInput);
  will(onConsecutiveCalls(  
  returnValue("one"),
  returnValue("two"),
  returnValue("three")));

And using Mockito:

String someInput = "test input";
when(myMockObject.myMethod(someInput ))
  .thenReturn("one", "two", "three");

But in C# using Moq, it is not nearly as concise.  A few different steps need to be taken.

  1. Create a variable to track the number of time the method has been invoked.
  2. Create an instance of a Func that will determine what to return each time it is invoked.
  3. In the call to Setup(), hand it the Func instance you just created and then also create a Callback to increment the counter created in step 1.

Here is an example:

var numCalls = 0;
Func<string> determineResponse = () =>
{
  if (numCalls == 0) {
    return "one";
  }  else {
    return "two;
  }
};
string someInput = "test input";
myMockObject.Setup(r => r.myMethod(someInput)).Returns(determineResponse).Callback(() => numCalls++);

Perhaps there is a simpler way in C# and Moq, but I have not found it.

Advertisements

About stevewall123

I am a Lead Software Engineer in Minneapolis working for Thomson Reuters. I am currently working on projects using Java, JavaScript, Spring, Drools, Hazelcast, Liquibase and Tomcat. Previously, I used C#, GWT, Grails, Groovy, JMS and JBoss Drools Guvnor. In the past I have worked on projects using J2EE, Swing, Webwork, Hibernate, Spring, Spring-WS, JMS, JUnit and Ant.
This entry was posted in C#, Moq and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s