Mocking Closed Objects

Recently I ran across a situation where I was using an object from a third party ORM tool that I wanted to mock for unit testing.  The method I wanted to test uses this particular third party object and calls methods on it that interact with our data store.   I just wanted to test my method and ensure it calls this third party object correctly, I don’t want the third party object to actually be called since it would then attempt to do its business of communicating with the application’s data store.  The problem was that the object does not implement any interface I can use to easily mock it through a mocking facility such as rhino mock.  Some mock facilities, such as rhino mock, will let you mock an actual object if the methods you want to call are virtual and can be overridden.  Unfortunately the methods I was interested in aren’t virtual so can’t extend the object and create a child class mock without having the real base methods fire.  This wouldn’t work since it was just those methods I wanted to fake.

I think I came up with a fairly slick solution, and a friend even told me this is the same solution proposed by Robert Martin in his book ‘Working With Legacy Code’, when encountering this situation.   All the classes and code below are only examples, they aren’t the code I was actually working on, there would be too much to explain if I tried to actually use that!

MockClosedClass

The class I want to mock is named ‘UnitOfWork’.  In order to create a type I can use for abstraction I created an interface, ‘IUnitOfWork’ that reflects all the methods in the class that I’m interested in mocking.  I cannot make the class ‘UnitOfWork’ implement my interface but what I can do, as shown above, is create a class that inherits from ‘UnitOfWork’ and have my child class, ‘MockAbleUnitOfWork’ implement my new interface.  In my code I  change any variables of ‘UnitOfWork’ and make them ‘IUnitOfWork’.  I also refactor my code so the ‘IUnitOfWork’ types are passed into methods that use them as arguments so I can replace them in testing with a mock object.  In my production code I then use an instance of my child class ‘MockAbleUnitOfWork’, which implements ‘IUnitOfWork’ and gets all its behavior from the ‘UnitOfWork’ class.  Although I cannot override the methods I’m interested in from ‘UnitOfWork’  when those methods are called on my child class the parent class provides the behavior.  Below you can see an example change.

OriginalClosedClass
Initial Code
Code Updated To Allow Replacement
Code Updated For Abstraction

The updated code allows me to use the overloaded ‘SaveStudentsWithGoodGrades’ method to pass in a mock object for testing where I can confirm that only students with a passing grade are added to the unit of work and then the unit of work is actually saved.  Now that the unit of work is abstracted I can test it without actually firing off any of the unit of work’s actually functionality.  Also, I didn’t have to do much to create this setup, my child class contains no new methods, it’s essentially empty.  This has allowed me to decrease the coupling in my system since now the method ‘SaveStudentsWithGoodGrades’ relies only on my interface, not on the third party object, and I control the interface.  If the third party object were to change, I could create an adapter the implements my interface and allow callers of ‘SaveStudentsWithGoodGrades’ to be completely free of any of the issues created by a change in this third party object.   I love it when changes for testing lead to either higher cohesion or lower coupling!

The one downside to this approach is that it will not work with a sealed class, if you can’t create a child class this approach won’t work.  It works great for non-virtual methods in non-sealed classes though, at  least it seemed to work in this case.

Leave a Reply

Your email address will not be published. Required fields are marked *