« Wiring the house for a Home Network - Pa... | Main | aideRSS - Now things are getting smarter... »

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.



Wednesday, December 19, 2007 5:40:07 AM (Pacific Standard Time, UTC-08:00)
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>();
Craig wilson
Wednesday, December 19, 2007 7:05:58 AM (Pacific Standard Time, UTC-08:00)
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. ;)
Wednesday, December 19, 2007 8:22:35 AM (Pacific Standard Time, UTC-08:00)
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.
Bryan Watts
Wednesday, December 19, 2007 10:02:48 AM (Pacific Standard Time, UTC-08:00)
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.
Wednesday, December 19, 2007 11:05:53 AM (Pacific Standard Time, UTC-08:00)
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!
Wednesday, December 19, 2007 1:26:09 PM (Pacific Standard Time, UTC-08:00)
"Slick"? You must have meant "Sliq", no? :-)
Wednesday, December 19, 2007 3:01:40 PM (Pacific Standard Time, UTC-08:00)
Wow that looqs really cool :). I only want one mocking framework in my life, but which one ?
OmegaSupreme
Thursday, December 20, 2007 1:39:57 AM (Pacific Standard Time, UTC-08:00)
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.
Thursday, December 20, 2007 2:41:22 AM (Pacific Standard Time, UTC-08:00)
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.
Friday, December 21, 2007 8:05:47 PM (Pacific Standard Time, UTC-08:00)
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
Tuesday, January 08, 2008 4:26:07 AM (Pacific Standard Time, UTC-08:00)
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.
Wednesday, January 09, 2008 9:18:48 AM (Pacific Standard Time, UTC-08:00)
Pingback from http://oakleafblog.blogspot.com/2008/01/linq-and-entity-framework-posts-for.html
Wednesday, January 30, 2008 5:40:24 AM (Pacific Standard Time, UTC-08:00)
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.

Contact

Sponsors

Hosting By

Hot Topics

Tags

Calendar

<November 2009>
SunMonTueWedThuFriSat
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

Archives

November, 2009 (5)
October, 2009 (19)
September, 2009 (11)
August, 2009 (12)
July, 2009 (21)
June, 2009 (26)
May, 2009 (16)
April, 2009 (13)
March, 2009 (17)
February, 2009 (17)
January, 2009 (18)
December, 2008 (32)
November, 2008 (17)
October, 2008 (22)
September, 2008 (16)
August, 2008 (14)
July, 2008 (25)
June, 2008 (19)
May, 2008 (17)
April, 2008 (17)
March, 2008 (26)
February, 2008 (21)
January, 2008 (28)
December, 2007 (19)
November, 2007 (17)
October, 2007 (31)
September, 2007 (39)
August, 2007 (37)
July, 2007 (43)
June, 2007 (37)
May, 2007 (32)
April, 2007 (38)
March, 2007 (29)
February, 2007 (46)
January, 2007 (31)
December, 2006 (27)
November, 2006 (31)
October, 2006 (32)
September, 2006 (39)
August, 2006 (34)
July, 2006 (40)
June, 2006 (18)
May, 2006 (31)
April, 2006 (34)
March, 2006 (30)
February, 2006 (38)
January, 2006 (44)
December, 2005 (19)
November, 2005 (34)
October, 2005 (24)
September, 2005 (37)
August, 2005 (20)
July, 2005 (24)
June, 2005 (33)
May, 2005 (16)
April, 2005 (22)
March, 2005 (34)
February, 2005 (15)
January, 2005 (37)
December, 2004 (28)
November, 2004 (30)
October, 2004 (34)
September, 2004 (22)
August, 2004 (34)
July, 2004 (18)
June, 2004 (64)
May, 2004 (49)
April, 2004 (21)
March, 2004 (29)
February, 2004 (29)
January, 2004 (36)
December, 2003 (25)
November, 2003 (24)
October, 2003 (59)
September, 2003 (42)
August, 2003 (24)
July, 2003 (44)
June, 2003 (29)
May, 2003 (21)
April, 2003 (30)
March, 2003 (27)
February, 2003 (47)
January, 2003 (50)
December, 2002 (31)
November, 2002 (38)
October, 2002 (44)
September, 2002 (15)
May, 2002 (2)
April, 2002 (4)

Google Ads