Mocking revisited – mocking a method and passing a parameter using FakeItEasy and Moq

by Oliver 21. June 2011 23:35

Finally, I’ve started mocking things in our kind of legacy project while building new functionality. Now, I wanted to replace some DAL service with a mock that would would just serve me some results instead of ramping up NHibernate, going to the DB and assembling all the entities for this test. At first I tried to use FakeItEasy as I liked the syntax more than that of Moq:

  1: var _geoObjectServiceMock = A.Fake<IGeoObjectService>();
  2: var results = new List<int>{ 1, 2, 3, ... };
  3: A.CallTo(() => _geoObjectServiceMock.GetSearchResultIds(A<GeoObjectSearchDesc>.Ignored))
  4:     .Returns(results);

This was easy. Just fix up the result you want the method to return and set it up. Well – I needed more. I needed to return my results list dependent on the GeoObjectSearchDesc parameter passed to the method. In short: I did not find a way to do this. I searched Google and Stackoverflow but to no avail. What I did find was an example using Moq showing exactly what I wanted to do. From Moq’s QuickStart wiki page:

  1: // access invocation arguments when returning a value
  2: mock.Setup(x => x.DoSomething(It.IsAny<string>()))
  3:     .Returns((string s) => s.ToLower());
  4: // Multiple parameters overloads available

So I quickly installed Moq using NuGet, e.g. from the Package Manager Console:

  1: Install-Package Moq -project Tests

Now I have something like this which is exactly what I was looking to do:

  1: var _geoObjectServiceMock = new Mock<IGeoObjectService>();
  2: var results = new List<int>{ 1, 2, 3, ... };
  3: _geoObjectServiceMock.Setup(svc => svc.GetSearchResultIds(It.IsAny<GeoObjectSearchDesc>()))
  4:                      .Returns<GeoObjectSearchDesc>(gosd => results.Take(gosd.PageSize).ToList());

That’s what I expected – to get control over the method parameter(s) inside the mock. Great! Thank you Moq.

Happy Coding,

Oliver

Comments (1) -

Tim Lovell-Smith United States
2/5/2014 9:52:45 PM #

I think A.CallTo().ReturnsLazily(Func<GeoObjectSearchDesc,List<int>>) would do what you wanted.

Comments are closed

About Oliver

shades-of-orange.com code blog logo I build web applications using ASP.NET and have a passion for javascript. Enjoy MVC 4 and Orchard CMS, and I do TDD whenever I can. I like clean code. Love to spend time with my wife and our children. My profile on Stack Exchange, a network of free, community-driven Q&A sites

About Anton

shades-of-orange.com code blog logo I'm a software developer at teamaton. I code in C# and work with MVC, Orchard, SpecFlow, Coypu and NHibernate. I enjoy beach volleyball, board games and Coke.