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



Using the RhinoAutoMocker that is part of StructureMap 2.5

One of the new features that is part of the next release of StructureMap 2.5 is a AutoMocking Container. 

What is an AutoMocking Container, well per Jacob over at Eleutian an AutoMocker is

AutoMockingContainer is simply a IoCContainer with a custom facility and dependency resolver that supplies a Mock (RhinoMock) for any interface that is resolved.

My definition is a little more straight forward and uses simpler word (remember I am a simpleton :))

An AutoMocking container is simply a tool that will inject mock dependencies into your object for you.

What I want to do today is show how an AutoMocking Container can reduce the amount of code/noise from your tests.   I am going to first show a tests that simply uses RhinoMocks then that same test that uses the RhinoAutoMocker

Test with only RhinoMocks

[Test]
public void NoAutoMocker()
{
	var mockProvider = MockRepository.GenerateMock<IPersistingRulesProvider>();
        var mockRepository = MockRepository.GenerateMock<ISynchronizationRepository>();
        var mockPersistanceProvider = MockRepository.GenerateMock<IPersistanceProvider>();
        var mockLogger = MockRepository.GenerateMock<ILogger>();

	// Expectations
        mockProvider.Expect(x => x.ExecuteRules(null)).IgnoreArguments().Throw(new Exception("Do not care what this is"));
        mockRepository.Expect(x => x.StartTransaction()).Repeat.Once();
        mockRepository.Expect(x => x.RollbackTransaction()).Repeat.Once();
        mockRepository.Expect( x => x.CommitTransaction() ).Repeat.Never();

	var persitingPipeline = new PersistingPipeline(mockProvider, mockPersistanceProvider, mockRepository, mockLogger);
        var result = persitingPipeline.PersistChanges(new DataSet(), 0, 0, 0);

	Assert.That( result, Is.Not.Empty );

	mockRepository.VerifyAllExpectations();
}

This code above has a bit of noise.  Because my object has a dependency on 4 other objects i need to create mocks for each of these.  This creates more work and just adds to the test noise.

Test with the RhinoAutoMocker

[Test]
public void WithAutoMocker()
{
	var mockPipeline = new RhinoAutoMocker<PersistingPipeline>();

	mockPipeline.Get<IPersistingRulesProvider>().Expect( x => x.ExecuteRules( null ) ).IgnoreArguments().Throw( new Exception( "Do not care what this is" ) );
	mockPipeline.Get<ISynchronizationRepository>().Expect(x => x.StartTransaction()).Repeat.Once();
        mockPipeline.Get<ISynchronizationRepository>().Expect(x => x.RollbackTransaction()).Repeat.Once();
        mockPipeline.Get<ISynchronizationRepository>().Expect(x => x.CommitTransaction()).Repeat.Never();

	var result = mockPipeline.ClassUnderTest.PersistChanges( new DataSet(), 0, 0, 0 );

	Assert.That( result, Is.Not.Empty );

}

The code above does not require me to create mocks for each of my dependencies, the AutoMocker will do that for me.

Also notice that when I need to set an expectation for a dependencies I can access it via the .Get<>() method. 

Till next time,

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



Comments

DotNetKicks.com said:

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

# October 5, 2008 7:15 PM

Silverlight Travel said:

Great. Much easer like without AutoMocking Container

# October 6, 2008 12:19 AM

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

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

# October 6, 2008 3:05 AM

chrissie1 said:

The only problem I have with this is that it needs an IoC to run the test, so you are actually adding a dependency to do the tests which makes 'm slightly more brittle. This is however a minor objection.

What do you think?

# October 6, 2008 7:10 AM

Derik Whittaker said:

@Chrissie

As i am a big fan of IoC and use them in most of my applications this is a non-issue for me.

Also, I think the savings of not having to manually create your mocks is worth the added dependency.

Finally, I do not see how this makes my tests more brittle.  In fact because I can change my constructor parameters without having to change my tests makes the test less brittle in my opinion.

# October 6, 2008 7:36 AM

chrissie1 said:

It's more brittle because it depends on the container being configured correctly. Perhaps not such a big deal but it is there. what if the default of your implementations changes? all four at the same time?

And I too am A big fan of IoC but I try to keep it out of my tests. Mostly because I can do the sam without. Of course if you have lots of dependencies then it would be eassier.

I remember Jeremy not being convinced at first, but he changed his mind.

It was just a thought, not a criticism.

# October 6, 2008 7:54 AM

Dew Drop - October 6, 2008 | Alvin Ashcraft's Morning Dew said:

Pingback from  Dew Drop - October 6, 2008 | Alvin Ashcraft's Morning Dew

# October 6, 2008 8:30 AM

jdn said:

Some would argue that the need for an AMC is/could be a code smell in the first place, along the lines of questioning why you need to wire up so many dependencies (could be a bad design).

Not sure if I buy that myself, I guess it depends.

# October 6, 2008 12:25 PM

Joshua Flanagan said:

@chrissie1 - You do not need to configure the container when using the automocker. Derik's sample code above is complete - he didn't hide the configuration part. All dependencies resolve to mocks, so there isn't any danger of brittle configuration. You CAN inject other non-mock objects into the container if you need to, but that would be specific to your test, and no more brittle.

@derik - I think you still need to verify your expectations when using the automocker. Something like "mockPipeline.VerifyAll()"

# October 7, 2008 8:20 AM

Derik Whittaker said:

@Joshua,

You are correct, I did leave out the verify code.

That was a simple oversight

# October 7, 2008 8:28 AM

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