Simplify Your Unit Tests With Auto Mocking: Part 1 – Helper Methods


After working on the Ninject.RhinoMocks automocking container, I started using it in my current project right away and it wasn’t long before I started simplifying the usage of it with helper methods in my base test class.

 

From “MockingKernel.Get()” To “Get()”

I got tired of calling MockingKernel.Get() all over the place, so I created a helper method in my base ContextSpecification class called Get(). This method does nothing more than forward calls to the MockingKernel.Get method, but it could easily be enhanced to do something more – like caching the object retrieved, so that the IoC container is not always resolving (even though it resolves to a singleton).

   1: protected T Get<T>()

   2: {

   3:     return MockingKernel.Get<T>();

   4: }

</div> </div>

This is a small change, but it makes a lot of code easier to ready. Compare this:

   1: [Test]

   2: public void it_should_do_that_thing()

   3: {

   4:     MockingKernel.Get<IMyView>().AssertWasCalled(v => v.ThatThing());

   5: }

</div> </div>

To this:

   1: [Test]

   2: public void it_should_do_that_thing()

   3: {

   4:     Get<IMyView>().AssertWasCalled(v => v.ThatThing());

   5: }

</div> </div>

A small amount of code reduction and a little easier to read.

 

From “Get().AssertWasCalled(…)” to “AssertWasCalled(…)” </h3>

After adding the Get code, I realized that I could simplify the assertion even further by creating a helper method that would call Get for me. RhinoMocks has two methods for AssertWasCalled. The first just takes the method and sets some defaults, like only expecting 1 call. The second allows you to specify method options for more advanced needs. I created to AssertWasCalled methods to mimic the RhinoMocks methods and call Get for me: </p>

   1: protected void AssertWasCalled<T>(Action<T> action)

   2: {

   3:     T mock = Get<T>();

   4:     mock.AssertWasCalled(action);

   5: }

   6:     

   7: protected void AssertWasCalled<T>(Action<T> action, Action<IMethodOptions<object>> methodOptions)

   8: {

   9:     T mock = Get<T>();

  10:     mock.AssertWasCalled(action, methodOptions);

  11: }

</div> </div>

This allowed me to simplify my specs down even further:

   1: [Test]

   2: public void it_should_do_that_thing()

   3: {

   4:     AssertWasCalled<IMyView>(v => v.ThatThing());

   5: }

   6:  

   7: [Test]

   8: public void it_should_do_the_other_thing_twice()

   9: {

  10:     AssertWasCalled<IMyView>(v => v.TheOtherThing(), mo => mo.Repeat.Twice());

  11: }

</div> </div>

This is less code to read and easier to understand.

 

A Full Spec Example

With these helper methods in place, a full specification is much easier to read, now:

</p> </p>
   1: public class when_doing_something_with_that_thing : ContextSpecification

   2: {

   3:     protected MyPresenter SUT;

   4:     

   5:     protected override void EstablishContext()

   6:     {

   7:         SUT = Get<MyPresenter>();

   8:     }

   9:     

  10:     protected override void When()

  11:     {

  12:         SUT.DoSomething();

  13:     }

  14:     

  15:     [Test]

  16:     public void it_should_do_that_thing()

  17:     {

  18:         AssertWasCalled<IMyView>(v => v.ThatThing());

  19:     }

  20:  

  21:     [Test]

  22:     public void it_should_do_the_other_thing_twice()

  23:     {

  24:         AssertWasCalled<IMyView>(v => v.TheOtherThing(), mo => mo.Repeat.Twice());

  25:     }

  26: }

</div> </div>

 

But Wait! There’s More!

It gets even better! In tomorrow’s blog post – part 2 of simplifying unit tests with automocking – I’ll reduce the full specification code even further by eliminating the need to declare and setup the System Under Test (SUT).

Albacore: Should We Continue To Support Ruby v1.8.6?