Devlico.Us
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @devlicious

Derik Whittaker

Thoughts on Software Development, .Net, OOP, Design Patterns and all things cool



My first impressions with Rhino Mocks 3.5 (beta)

I finally got around to downloading and playing with the forthcoming release of Rhino Mocks v3.5 (more info here from Ayende).

The major changes to this version is that the syntax has been revamped to allow for the new language features in .Net 3.5.  Another big change with this release is that the dreaded Record-Replay semantics have been depreciated (although I have to admit that they never bothered me).

What I thought I would do today is do a little comparison with Rhino 3.5 against Rhino 3.4 (and older) as well as compare it to Moq as this mocking framework has been getting a lot of buzz lately.

The example below is a pretty straight forward example where I need to mock out my data repository for a test and I want to ensure that the correct call is actually made.

Rhino 3.5 Syntax

var admin = new Admin();
MockRepository mockRepository = new MockRepository();
var adminRepository = mockRepository.StrictMock< IAdminRepository >();

adminRepository.Expect( x => x.GetSiteTotals() ).Return( new SiteTotals() );

ObjectFactory.InjectStub( typeof( IAdminRepository ), adminRepository );

var siteTotals = admin.GetSiteTotals();

... Asserts here....
            
mockRepository.VerifyAllExpectations();

Rhino 3.4 and older syntax

MockRepository mockRepository = new MockRepository();
var admin = new Admin();
var adminRepository = mockRepository.CreateMock();

using ( mockRepository.Record() )
{
    Expect.Call( adminRepository.GetSiteTotals() ).Return( new SiteTotals() );
}

ObjectFactory.InjectStub( typeof( IAdminRepository ), adminRepository );
using ( mockRepository.Playback() )
{
    var siteTotals = admin.GetSiteTotals();

    ... Asserts here....

    mockRepository.VerifyAll();
}

Moq Syntax

var admin = new Admin();
var mockAdminRepository = new Mock< IAdminRepository >();

mockAdminRepository.Expect( x => x.GetSiteTotals() ).Returns( new SiteTotals() );

ObjectFactory.InjectStub( typeof ( IAdminRepository ), mockAdminRepository.Object );

var siteTotals = admin.GetSiteTotals();

... Asserts here....

mockAdminRepository.VerifyAll();

Rhino 3.5 compared to older versions of Rhino
Lets take a quick look at the syntax differences between the new version and the old. 

First thing you will notice with 3.5 is that it removes the need to explicitly perform a record/replay.  I personally never had an issue with this syntax, but it does remove noise from your code and this is a good thing.

Next you may notice that there is no more need to use the Expect object to set your expectations.  With 3.5 you can simply use the Extension Method Expect and it will do the same thing (love this).

Lastly take notice to how I am calling mockRepository.VerifyAllExpectations() in place of mockRepository.VerifyAll().  From what I can tell this is just a naming change for clarity sake, but I like it.

Rhino 3.5 compared to Moq
Lets take a quick look at the syntax differences between Rhino 3.5 and Moq.

Like the new version of Rhino you do not need to implement the Record/Replay semantics when creating your tests, and this is good as I said above because it removes noise.

First you will notice that with Moq u create all your objects via the 'Mock' object were with Rhino you use the MockRepository.  They both do the same thing, however with Moq the object you get back is NOT the actual type you requested, it is a wrapper around your type that is used for testing.  Personally I find Moq's syntax a little annoying and clumsy.

Next take notice that when you want to get access to the actual type instance of your mock you have to do mockAdminRepository.Object.  This is fine, but is just one more thing I have to remember to do.  I am always forgetting to add the .Object and my test will fail because of it.

Last, because Rhino still creates all the mocks out of the MockRepository you are able to call mockRepository.VerifyAllExpectations() one time to ensure that all expectations where met.  However, with Moq you need to call mockAdminRepository.VerifyAll() on each mock object (if there is a better way in Moq, please let me know).  To me having to potentially call .VarifyAll() multiple times just adds more noise to my test.

Now that I have spent a little time playing with Rhino 3.5, I have to say I am hooked.  In fact, I think i am going to gut my tests for DimeCasts.net that were originally written in Moq and replace them with Rhino 3.5.

Till next time,

[----- Remember to check out DimeCasts.Net -----]



Comments

Paul Rayner said:

Derik,

Thanks for posting on these. Very helpful.

I'm really looking forward to playing with Rhino Mocks 3.5 (amongst other things!) after I get VS2008 installed this weekend.

I, for one, never got the record-replay syntax. I much prefer the arrange-act-assert structure that Oren has now implemented. For me it means less syntactical cognitive dissonance between state-based and interaction-based approaches.

Cheers,

Paul.

# June 27, 2008 9:38 AM

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# June 27, 2008 9:51 AM

Will said:

I chose MoQ over Rhino to replace the in-house stub making nonsense we used on my current project (used because we didn't want to spend the time learning a mock framework).

I've got Rhino still in the background, in case I hit something that MoQ can't do.  I haven't gotten used to the way Rhino uses a factory, so its not a big deal at all to deal with the mock containers themselves.  In fact, I have been writing code around the mocks and my objects to make the framework even easier to use.  

For example, I have a static class in my test project that holds all mocks for me.  It also has extension methods for my interfaces, so I can do this:

target.Log.Mock().Expect(....

It would be trivial to add a factory method to the static class and a VerifyAll() method.  

# June 27, 2008 10:27 AM

Derik Whittaker said:

@Will,

So what you are saying is that because Moq caused u friction you had to create a few helper methods to reduce that friction.  

However, the new release of Rhino has all that built in and does not require you to write that code.

Ask me and I say that Rhino would make life better/easier and cause less friction.

# June 27, 2008 10:35 AM

Chris Canal said:

I'm a long time user of Rhino and never really found the Record/Playback an issue.  I haven't had a chance to play around with 3.5, but I do like the look of the new syntax.

I have just finished a project where Moq was used, and did like using it.  Moq has a Mock Factory that you can use like the Mock Repository, taking the pain away of having to call VerifyAll on each mocked object.

The biggest pain point for me is losing the Auto Mocking Container.  I have thrown together a very basic Moq version, but it doesn't do everything the AMC does

# June 27, 2008 12:08 PM

Darrell Mozingo said:

It looks like there's been a mock factory in Moq since at least version 1.5, which enables you to do a single VerifyAll call:

www.hanselman.com/.../topic161-moq-mocking-the-c-30--linq--lambdas-way.aspx

var factory = new MockFactory(MockBehavior.Default);

var mock = factory.Create<ICloneable>();

mock.Expect(cloneable => cloneable.Clone());

factory.VerifyAll();

So you still have the option, and it doesn't add any noise over Rhino Mocks 1.5. I'd personally say Rhino Mocks 1.5 is equal to Moq in terms of the API and noise, and both are better than Rhino Mocks 1.4. Granted, Rhino Mocks has been around longer and has a more robust API, but you usually don't need all of that, which is why we're giving Moq a shot on our new project. So far so good.

Great article, though.

# June 27, 2008 2:01 PM

Derik Whittaker said:

@Darrell,

Thanks, I was not aware that Moq had the factory.  ony have used it on 1 project.

# June 27, 2008 2:07 PM

Dew Drop - June 29, 2008 | Alvin Ashcraft's Morning Dew said:

Pingback from  Dew Drop - June 29, 2008 | Alvin Ashcraft's Morning Dew

# June 29, 2008 7:55 AM

Daniel Cazzulino said:

Thanks for the feedback on Moq Derik.

The .Object thing in Moq is certainly annoying. I basically had to choose between adding mocking "noise" to ALL of your objects (what Rhino is doing by adding Expect as an extension method on Object and letting it fail at runtime if you make a mistake, and polluting intellisense) or add the .Object thing.

Ideally, you should have been able to implicitly cast your mock to your interface, so that the choice would have been yours, but the compiler doesn't allow that :(.

Fortunately, it's not that your tests will *fail*, they won't even *compile*, so forgetting the .Object qualifier is very easy to catch (although no less annoying, I agree).

# June 30, 2008 12:44 AM

Reflective Perspective - Chris Alcock » The Morning Brew #125 said:

Pingback from  Reflective Perspective - Chris Alcock  &raquo; The Morning Brew #125

# June 30, 2008 3:30 AM

Code Monkey Labs said:

Happy 4th of July! General First Impressions of Rhino Mocks 3.5 Beta : Derik Whittaker takes a look at the beta of Rhino Mocks 3.5. One of the major new features is that the syntax has been updated to take advantage of the new language features in .NET

# July 7, 2008 9:38 PM

3 Below » My first impressions with Rhino Mocks 3.5 (beta) said:

Pingback from  3 Below &raquo; My first impressions with Rhino Mocks 3.5 (beta)

# July 12, 2008 4:43 PM

Buspar. said:

Buspar.

# November 13, 2008 9:20 PM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Derik Whittaker

Derik is a .Net Developer/Architect specializing in WinForms working out the northern suburbs of Chicago. He is also believer and advocate for Agile development including SCRUM, TDD, CI, etc.

When Derik is not writing code he can be found spending time with his wife and young son, climbing on his bouldering wall, watching sports (mostly baseball), and generally vegging out. Check out Devlicio.us!

Our Sponsors

Proudly Partnered With


This Blog

Syndication

News