Scott Hanselman

Moq: Linq, Lambdas and Predicates applied to Mock Objects

December 19, 2007 Comment on this post [13] Posted in ASP.NET | Learning .NET | LINQ | Musings | Programming
Sponsored By

iStock_000004250790XSmall Kzu and friends have a new pet project called Moq, which may be the coolest derivative open source project name ever. But, before I get into that...

There's lots of interesting Mock Object Frameworks out there. The ones that you'll always hear about (because they are awesome) are Rhino.Mocks and TypeMock (Full Disclosure: we used TypeMock at Corillian, my last job. Here's a Case Study that was done.)

Both frameworks are very powerful. Here's Phil Haack's post on mocking IHttpRequest and IHttpReponse in the new MVC Framework using Rhino Mocks. Here's Travis Illig using TypeMock to mock the actual HttpContext (not the MVC interface) earlier this year.

One of the things that often comes up when comparing Mock Frameworks, after their core capabilities, is their syntax.

Early Mocking frameworks like NMock (which isn't really used much anymore) mock interfaces and use a quasi-fluent interface that breaks down when you start referring to methods and properties using strings. Why is this bad? Well, for one it means when you refactor using tools like CodeRush or Resharper the system doesn't realize that a string referring to "Foo" means the method x.Foo(). For example, here's a snippet from NMock:

   mocks = new Mockery();
   ITransferFundsView mockView = mocks.NewMock<ITransferFundsView>();
   Expect.Once.On(mockView).GetProperty("Amount").Will(Return.Value(200.00));

You get the idea. We're referring to a property "FromAccount" via a string passed into GetProperty, rather than in a strongly typed way.

RhinoMock is smarter, and might look like this snippet:

mockView = (ITransferFundsView)mocks.CreateType(typeof(ITransferFundsView));

SetupResult.For(mockView.Amount).Return(200.00);

See how much clearer it is to just call the property?

TypeMock is implemented as a profiler under the covers so it can do some pretty powerful stuff like "recording" your expectations do you can Tivo them back. So with TypeMock you'd do this using their "Natural TypeMock" syntax.:

 using (RecordExpectations recorder = RecorderManager.StartRecording())
{
double foo = mockView.Ammount;
recorder.Return(200.00);
}
//the next time you call mockView.Ammount, it will return 200.00.

Either way, you can see why both RhinoMocks and TypeMock's syntaxs would be refactoring tool friendly. They compile against the real method signatures and properties so they can been "seen" by the tool. As for which one you like, that's a religious argument I won't get into, but depending on what you need, both are fine choices and they each have a very friendly syntax.

Why all this background? There's a new Mocking Framework in town, and it's C# 3.0 specific using LINQ Expression Trees and Lambda Expressions.

The same snippet in Moq might look like this:

var mockView = new Mock<ITransferFundsView>;
mockView.Expect(x => x.Amount).Returns(200.00);

Note the use of Generics for the Type ITransferFundsView and the interesting use of a Lambda expression to indicate a mocked call to the Amount property. Check out the Moq QuickStart for more interesting examples.

Here's another deeper, more interesting example that shows how lambdas might really be a great feature for any .NET Mock Framework. It's the "It" class combined with the power of predicates.

The It class provides for a kind of wildcard support. There's an IsAny, IsInRange and IsRegex. The coolest one though is the plain It.Is method that receives a predicate!

mock.Expect(x => x.DoInt(It.Is<int>(i => i % 2 == 0))).Returns(1);

Here the mocked object will return the value 1 only if the integer passed to the DoInt method is an even number.

The cool thing about this approach is that you don't need the mocking library to provide all the filters you need, as you can simply pass a predicate for any condition you can dream of.

Slick. Moq is definitely a project to watch.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
December 19, 2007 17:40
FYI: You noted the genericness of Moq, but have left that out of Rhino Mocks. Rhino Mocks could also do this...

mockView = mocks.CreateMock<ITransferFundsView>();
December 19, 2007 19:05
Not to add fuel to the Holy-war-fire... but Rhino.Mocks also supports the Record + Playback syntax similar to TypeMock.

Yes, I'm a bit of a Rhino.Mocks fanboy... but I blame it on Phil - he's the one that pushed it on me in the first place. ;)
December 19, 2007 20:22
You can drop the <int> on It.Is(i => i % 2 == 0) - it will be inferred based on the expected type specified by DoInt().

Expression tress are the best part of Linq.
December 19, 2007 22:02
Rhino Mocks already supports similar syntax, see Ayende's response.

In Moq it looks like this:
mock.Expect(x => x.DoInt(It.Is<int>(i => i % 2 == 0))).Returns(1);

and in Rhino Mocks it looks like this:
Expect.Call( () => foo.DoInt(0) ).Constraints( Is.Matching<int>( i => i % 2 == 0) ).Return(1);

This style is doable with C# 2.0 anonymous delegates, the alternative lamda syntax just makes it look cleaner.
December 19, 2007 23:05
Wow, looks like Rhino kicks more ass than I thought. That's a VERY deep project. There's a LOT you can do in Rhino. I'll dig deeper, thanks!
December 20, 2007 1:26
"Slick"? You must have meant "Sliq", no? :-)
December 20, 2007 3:01
Wow that looqs really cool :). I only want one mocking framework in my life, but which one ?
December 20, 2007 13:39
Sorry to be picky, but I'd be grateful if you didn't refer to one framework as "smarter" than another, there are different trade-offs. NMock2 put more emphasis on an embdedded DSL that was declarative and where autocompletion would guide the programmer as to what to do next. It also had all the hooks for user-specified constraints. The cost was the use of strings. Rhino and others took the easymock route and prioritised record/playback. jMock2 is something of a hybrid.

All of these libraries are a bit like (in the famous old phrase) a dog walking on two legs, impressive we can do it at all. They stretch the host syntax further than it should go, but that's the best we can do until we get to more helpful languages.
December 20, 2007 14:41
Valid nit, Steve, I appreciate your comment. "Smarter" probably wasn't the best word to use. I'm just really internally prejudiced against strings used in that context, so I knee-jerked to that term. However, your point is well taken.
December 22, 2007 8:05
Brian, you cannot leave the <int> out as it doesn't compile.
I believe the source of the error is that apparently type inference does not work on method groups, as explained by Eric Lipert
January 08, 2008 16:26
I did similar thing for NMock2 some time ago (more like an experiment).
I think making a new framework just for the new syntax feature is a bit of an overkill.
January 09, 2008 21:18
Pingback from http://oakleafblog.blogspot.com/2008/01/linq-and-entity-framework-posts-for.html
January 30, 2008 17:40
I've been playing around with writing some extension methods for TypeMock that allows for the use of lambdas as expression trees to set up expectations, much like the moq syntax :)

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.