Mocking successive calls of similar type via sequential mocking

Posted by mehfuzh on ASP.net Weblogs See other posts from ASP.net Weblogs or by mehfuzh
Published on Mon, 31 May 2010 14:35:18 GMT Indexed on 2010/05/31 14:43 UTC
Read the original article Hit count: 491

Filed under:
|
|

In this post , i show how you can benefit from  sequential mocking feature[In JustMock] for setting up expectations with successive calls of same type.  To start let’s first consider the following dummy database and entity class.

  1. public class Person
  2. {
  3.     public virtual string Name { get; set; }
  4.     public virtual int Age { get; set; }
  5. }
  6.  
  7. public interface IDataBase
  8. {
  9.     T Get<T>();
  10. }

Now, our test goal is to return different entity for successive calls on IDataBase.Get<T>(). By default, the behavior in JustMock is override , which is similar to other popular mocking tools. By override it means that the tool will consider always the latest user setup.

Therefore, the first example will return the latest entity every-time and will fail in line #12:

  1. Person person1 = new Person { Age = 30, Name = "Kosev" };
  2. Person person2 = new Person { Age = 80, Name = "Mihail" };
  3.  
  4. var database = Mock.Create<IDataBase>();
  5.  
  6. Queue<Person> queue = new Queue<Person>();
  7.  
  8. Mock.Arrange(() => database.Get<Person>()).Returns(() => queue.Dequeue());
  9. Mock.Arrange(() => database.Get<Person>()).Returns(person2);
  10.  
  11. // this will fail
  12. Assert.Equal(person1.GetHashCode(), database.Get<Person>().GetHashCode());
  13.  
  14. Assert.Equal(person2.GetHashCode(), database.Get<Person>().GetHashCode());

We can solve it the following way using a Queue and that removes the item from bottom on each call:

  1. Person person1 = new Person { Age = 30, Name = "Kosev" };
  2. Person person2 = new Person { Age = 80, Name = "Mihail" };
  3.  
  4. var database = Mock.Create<IDataBase>();
  5.  
  6. Queue<Person> queue = new Queue<Person>();
  7.  
  8. queue.Enqueue(person1);
  9. queue.Enqueue(person2);
  10.  
  11. Mock.Arrange(() => database.Get<Person>()).Returns(queue.Dequeue());
  12.  
  13. Assert.Equal(person1.GetHashCode(), database.Get<Person>().GetHashCode());
  14. Assert.Equal(person2.GetHashCode(), database.Get<Person>().GetHashCode());

This will ensure that right entity is returned but this is not an elegant solution. So, in JustMock we introduced a  new option that lets you set up your expectations sequentially. Like:

  1. Person person1 = new Person { Age = 30, Name = "Kosev" };
  2. Person person2 = new Person { Age = 80, Name = "Mihail" };
  3.  
  4. var database = Mock.Create<IDataBase>();
  5.  
  6. Mock.Arrange(() => database.Get<Person>()).Returns(person1).InSequence();
  7. Mock.Arrange(() => database.Get<Person>()).Returns(person2).InSequence();
  8.  
  9. Assert.Equal(person1.GetHashCode(), database.Get<Person>().GetHashCode());
  10. Assert.Equal(person2.GetHashCode(), database.Get<Person>().GetHashCode());

The  “InSequence” modifier will tell the mocking tool to return the expected result as in the order it is specified by user. The solution though pretty simple and but neat(to me) and way too simpler than using a collection to solve this type of cases.

Hope that helps

P.S. The example shown in my blog is using interface don’t require a profiler  and you can even use a notepad and build it referencing Telerik.JustMock.dll, run it with GUI tools and it will work. But this feature also applies to concrete methods that includes JM profiler and can be implemented for more complex scenarios.

© ASP.net Weblogs or respective owner

Related posts about c#

Related posts about agile