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
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.
- public class Person
- {
- public virtual string Name { get; set; }
- public virtual int Age { get; set; }
- }
- public interface IDataBase
- {
- T Get<T>();
- }
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:
- Person person1 = new Person { Age = 30, Name = "Kosev" };
- Person person2 = new Person { Age = 80, Name = "Mihail" };
- var database = Mock.Create<IDataBase>();
- Queue<Person> queue = new Queue<Person>();
- Mock.Arrange(() => database.Get<Person>()).Returns(() => queue.Dequeue());
- Mock.Arrange(() => database.Get<Person>()).Returns(person2);
- // this will fail
- Assert.Equal(person1.GetHashCode(), database.Get<Person>().GetHashCode());
- 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:
- Person person1 = new Person { Age = 30, Name = "Kosev" };
- Person person2 = new Person { Age = 80, Name = "Mihail" };
- var database = Mock.Create<IDataBase>();
- Queue<Person> queue = new Queue<Person>();
- queue.Enqueue(person1);
- queue.Enqueue(person2);
- Mock.Arrange(() => database.Get<Person>()).Returns(queue.Dequeue());
- Assert.Equal(person1.GetHashCode(), database.Get<Person>().GetHashCode());
- 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:
- Person person1 = new Person { Age = 30, Name = "Kosev" };
- Person person2 = new Person { Age = 80, Name = "Mihail" };
- var database = Mock.Create<IDataBase>();
- Mock.Arrange(() => database.Get<Person>()).Returns(person1).InSequence();
- Mock.Arrange(() => database.Get<Person>()).Returns(person2).InSequence();
- Assert.Equal(person1.GetHashCode(), database.Get<Person>().GetHashCode());
- 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