Ninject.RhinoMocks: Auto Mocking Container For .NET 3.5 and Compact Framework 3.5

Earlier today, I decided I was tired of calling RhinoMocks directly. I love RhinoMocks. It’s a great tool and I don’t want to write tests without it (or another mocking framework like Moq or whatever…). But I’m tired of all the boring “declare a variable here, mock the object there, pass the object to the constructor here” junk that I have to do to get a mock object into my class under test.

Here’s an example of what I’m talking about:

   1: public class when_doing_something: basecontext

   2: {

   3:   private ISomeView View;

   4:   private SomePresenter Presenter;

   5:  

   6:   public override void EstablishContext()

   7:   {

   8:       View = MockRepository.GenerateMock<IView>();

   9:       Presenter = new Presenter(View);

  10:   }

  11:   

  12:   public override void When()

  13:   {

  14:       Presenter.DoSomething();

  15:   }

  16:   

  17:   [Test]

  18:   public void it_should_show_something()

  19:   {

  20:     View.AssertWasCalled(v => v.ShowThatThing());

  21:   }

  22: }

Line 3: declare a variable here

Line 8: mock the object here

Line 9: pass it to the class under test

Line 20: assert against it

It’s even more annoying when I have to mock things that I don’t care about, or when I have 5 or 6 or more things to mock (and yes, I know that having that many dependencies is a design smell. I’m not working on a pure greenfield app, so I don’t have the luxury of designing everything ‘correctly’).

… what can I say… I’m lazy. I’d rather ignore the ceremony of declaring the variable, mocking it and passing it to my class. Let me get my class and ask for the mock if I need it. I’m not trying to do anything crazy or bad, or let myself get away with poor design problems. I’m just trying to reduce the amount of code that I have to write in my tests. Maybe it’s the ruby developer in me, lashing out against the ceremony of C# again… whatever it is, I want an auto-mocking container for ninject and rhino mocks.

Now I know there is a general sense of “NO!!!!!” in the alt.net crowd these days… but I don’t understand that. Just because you can abuse a tool, doesn’t mean you should or will. I like wielding triple-edged swords with poison-tip spikes on the handle. It give me power and flexibility to get things done… and yes, the occasional debilitating injury… but hey, a little pain just means I’m learning what not to do, right? :)

 

Automocking With Ninject And RhinoMocks

After doing a bit of googling, I found a stack overflow question with the basic code to get this running. I had a hard time getting that to work, though, so I scrapped it and started fresh from a copy of ninject.moq. A little while later, I have a basic working auto-mocking container for ninject and rhino mocks.

Now I can create a MockingKernel in my basecontext class and change my test code to run like this:

   1: public class when_doing_something: basecontext

   2: {

   3:   private SomePresenter Presenter;

   4:  

   5:   public override void EstablishContext()

   6:   {

   7:       Presenter = mockingKernel.Get<SomePresenter>();

   8:   }

   9:   

  10:   public override void When()

  11:   {

  12:       Presenter.DoSomething();

  13:   }

  14:   

  15:   [Test]

  16:   public void it_should_show_something()

  17:   {

  18:     mockingKernel.Get<IView>().AssertWasCalled(v => v.ShowThatThing());

  19:   }

  20: }

Line 18: get the view and assert against it

There’s only a few lines of code difference in this simple example, so it seems like a wash. When you are dealing with multiple dependencies, though, it makes the code much easier to write.

As a real-world example, after implementing this, I was able to reduce my test code by about 12 lines because I only needed 2 of the mocked objects for assertions. The rest of them were there for ‘support’ and other behaviors, but needed to be there to prevent null reference exceptions. With the auto mocking container in place, I didn’t need to declare a variable, mock, or pass the other dependencies into the class under test. I let the auto-mocking container do that for me.

 

Ninject.RhinoMocks And Ninject.RhinoMocks.CF

If you’d like to use this functionality, you can grab the source code from github. There are two different version available – one for full .net 3.5 and another for .net 3.5 compact framework.

Please note, though, that I wrote this code for me and built in the behavior that I wanted. All mocked objects are essentially singleton instances so every time you request one from the kernel, it returns the same one. Be sure to call kernel.Reset(); in your teardown, so you don’t get mock objects bleeding over between test fixtures.

Also note that this code is a bit of a hack, as I am not entirely sure about the implementation needs of ninject. I’ve asked for Ian Davis’ input on the code and he’s said he’ll review it… but until that happens, and until I get a chance to “clean up” the code, there’s no promises about the quality of this work.

 

Ninject.RhinoMocks:

 

Ninject.RhinoMocks.CF:


Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Derick Bailey

Derick Bailey is an entrepreneur, problem solver (and creator? :P ), software developer, screecaster, writer, blogger, speaker and technology leader in central Texas (north of Austin). He runs SignalLeaf.com - the amazingly awesome podcast audio hosting service that everyone should be using, and WatchMeCode.net where he throws down the JavaScript gauntlets to get you up to speed. He has been a professional software developer since the late 90's, and has been writing code since the late 80's. Find me on twitter: @derickbailey, @mutedsolutions, @backbonejsclass Find me on the web: SignalLeaf, WatchMeCode, Kendo UI blog, MarionetteJS, My Github profile, On Google+.
This entry was posted in .NET, Behavior Driven Development, Brownfield, C#, Compact Framework, Ninject, RhinoMocks, Unit Testing. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.lostechies.com/members/louissalin/default.aspx Louis Salin

    I’ve heard (or read…) that automocking is equivalent to taking weight loss pills while still eating cheesburgers for breakfast. Okay, I just made that up!

    My point is, and I’m in no way in a position to opine on the matter, that the pain of mocking might be due to design issues. Hiding the pain with a tool won’t make the cause go away.

    So maybe in this case it’s a very benign use of an automocker, but as the code base grows, the automocker will hide pain points that would otherwise become immediately obvious, no?

  • Justice~!

    I’m a bit surprised you didn’t just use a different Ninject module for testing that used rhinomocks to return a mocked dependency; would seem to be the easiest way?

  • http://www.lostechies.com/members/derick.bailey/default.aspx derick.bailey

    @Louis – yeah, that’s the “big problem” that people complain about when they say auto mocking containers are bad. honestly, that’s a pretty weak excuse for not teaching developers how to spot too many dependencies as a part of bad design. trust your team. if they get it wrong, teach them right. :)

    @Justice – that would only distribute the problem. rather than having my mocks setup in the area that they are used, i’d have to register them in a completely different class. worse, i wouldn’t know whether or not they were registered already, so i’d have to constantly check to see if they are when i am setting up a class to be tested.

  • Justice~!

    @Derick, I don’t know man – the pain of that had been pretty minimal for me! But then again once you get into larger domain spaces it might be more difficult to keep track, so I can see the other side too.