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

Jeremy D. Miller -- The Shade Tree Developer

Under the hood and working with .Net, TDD, Software Design, and Agile Stuff

Best and Worst Practices for Mock Objects

Mock objects are like any other tool.  Used one way they’re a huge time saver.  In other cases they can easily create more work and degrade the quality of the testing code.  In this post I’ll try to present some best and worst practices for utilizing mock objects.  Sadly, every “bad” practice described is something I’ve either done or seen done.

 

This is the third in a planned series of five posts on mock objects:

 

  1. Introduction to Mocks and Stubs
  2. When and Why to use Mocks and Stubs
  3. Best Practices for Mocks (this post)
  4. Constraints and other Mocking Tricks
  5. Attaching Mocks and Stubs with StructureMap (by request)

 

Mocking Interfaces and Classes outside Your Code

 

Be careful about mocking or stubbing any interface that is outside your own codebase.  If you don’t truly understand the semantics and proper usage of an interface you don’t have any business mocking that interface in a unit test.  My best advice is to create your own interface to wrap the interaction with the external API classes. 

 

The best example from my memory was a security subsystem that retrieved security authorization and user information from Active Directory.  We created a class that queried Active Directory directly (with a painful detour through ADAM) and wrote tests that were fully connected.  Technically we could have probably mocked the System.DirectoryServices classes somehow and just verified that we used the correct LDAP query command, but I don’t think it would have added any value.  The reason I think a mock would have been useless is that determining the correct LDAP query string to return the correct results was the majority of the effort.  I can write SQL queries in my sleep and XPath expressions when I’m merely drowsy, but the LDAP query syntax is pretty wacky (and poorly documented in my experience).

 

Instead of trying to mock the access to Active Directory, create your own coarse-grained interface for retrieving user information that will encapsulate the AD access.  Besides the testability gain, it’ll keep your other security code decoupled from the storage so that you can chuck the Active Directory strategy when your aggravation level gets too high.  This interface is safe to mock.

 

      public interface IUserInformationStore

      {

            UserInformation FindUser(string userName);

            UserInformation[] FindUsersInRole(string roleName);

      }

 

 

Avoid Mocking Fine-Grained or Chatty Interfaces

 

Don’t mock fine grained interfaces.  You’ll wear off the skin on your fingertips and the tests will NOT be intention revealing. 

 

Specifically, do not mock happy, funny ADO.Net (or JDBC for the Java crowd).  Just think of how many different ADO.Net objects and lines of code it takes to make a typical call to the database.   I’ve watched a couple of people try to write unit tests on their data access code by mocking IDbConnection, IDbCommand, and the various IDataParameter objects.  It’s too much effort for too little gain.  My advice is to just test the data access code against the actual database with integration tests.  For the most part I think testing persistence code without the database is a complete waste of time.  I’d make an obvious exception for data access frameworks and code that generates sql commands though.

 

By all means, mock the database in your unit tests, but do it in the right way.  With the exception of a DataSet (maybe), I don’t think you should ever expose any ADO.Net objects in the public interface that your data access classes expose to the rest of the system.

 

If you have a chatty interface, see if you can bunch the calls into some sort of coarse parameter object.  Fowler describes this in his Refactoring book as the Introduce Parameter Object refactoring.  As an example, consider the case of testing user interface screen logic in an ASP.Net application.  One of the first things you need to do is isolate as much code as possible from the ASP.Net runtime objects (you can create an HttpContext in a unit test, but it’s the blackest magic).  We can’t mock the Session directly, but we can put an interface in front of the Session to do state management.

 

      public struct SessionConstants

      {

            internal const string SORT_KEY = "Sort";

            internal const string NAME_FILTER_KEY = "NameFilter";

            internal const string PAGE_NUMBER_KEY = "PageNumber";

            internal const string DATASET_KEY = "Data";

      }

 

      public interface ISession

      {

            string GetStringValue(string key);

            void SetStringValue(string key, string sessionValue);

           

            DataSet GetDataSetValue(string key);

            void SetDataSetValue(string key, DataSet data);

      }

 

      public class SessionWrapper : ISession

      {

            private HttpSessionState _session;

 

            public SessionWrapper()

            {

                  _session = HttpContext.Current.Session;

            }

 

            public string GetStringValue(string key)

            {

                  return (string) _session[key];

            }

 

            public void SetStringValue(string key, string sessionValue)

            {

                  _session[key] = sessionValue;

            }

 

            public DataSet GetDataSetValue(string key)

            {

                  return (DataSet) _session[key];

            }

 

            public void SetDataSetValue(string key, DataSet data)

            {

                  _session[key] = data;

            }

      }

 

We can now test any web page controller class by using a mock object as a substitute for the Session.  The ISession and SessionWrapper pair will definitely make unit testing the web page controller classes easier, but it forces us into a lot of setup calls in the unit tests for each piece of state (page number, sorting expression, user preferences, etc.).  I think it also creates an ugly coupling from the controllers to the storage mechanism and structure.  A better approach in my opinion is to create a coarse grained class to hold the web page state and a new interface for retrieving the state management that completely decouples the actual storage mechanism.

 

      public class PageState

      {

            private string _sort;

            private string _filter;

            private int _pageNumber;

            private DataSet _data;

 

            public PageState(string sort, string filter, int pageNumber, DataSet data)

            {

                  _sort = sort;

                  _filter = filter;

                  _pageNumber = pageNumber;

                  _data = data;

            }

 

            public string Sort

            {

                  get { return _sort; }

                  set { _sort = value; }

            }

 

            public string Filter

            {

                  get { return _filter; }

                  set { _filter = value; }

            }

 

            public int PageNumber

            {

                  get { return _pageNumber; }

                  set { _pageNumber = value; }

            }

 

            public DataSet Data

            {

                  get { return _data; }

                  set { _data = value; }

            }

      }

 

 

      public interface IStateService

      {

            PageState RetrieveState();

            void StoreState(PageState state);

      }

 

Now all it takes to setup the mock object in a unit test for a controller class is an expectation for the RetrieveState() method and another for the StoreState() method.  The session state for the test can be quickly setup by calling the constructor function on the PageState object.

 

In a comment to my last post Ayende Rahein pointed out that excessive numbers of fine-grained expectations will make the tests very brittle to changes in the code.  Been there, done that.

 

How Many Mock Objects in any Given Test?

 

How many mock objects are too many?  I’ve worked with some people before that felt that there should never be more than 1-2 mock objects involved in any single unit test.  I wouldn’t make a hard and fast rule on the limit, but anything more than 2 or 3 should probably make you question the design.  The class being tested may have too many responsibilities or the method might be too large.  Look for ways to move some of the responsibilities to a new class or method.  Excessive mock calls can often be a sign of poor encapsulation. 

 

Inline with Jim Shore’s Reflective Design writing, unit tests and mock objects are another means to gather feedback about your code and design.  If you’re having difficulty using a mock object in a unit test, or you’re incurring more setup overhead in your tests than you’d like, it’s frequently a sign that you need to reconsider your class design.  In other words, too much mocking, either in the number of mock objects or the setup code, in any single unit test is a Coding Smell.

 

Minimizing the number of mock objects necessary for any given unit test is a very effective way of keeping the Cyclomatic Complexity of your classes below an acceptable level.

 

 

Only Mock your Nearest Neighbor

 

Ideally you only want to mock the dependencies of the class being tested, not the dependencies of the dependencies.  From hurtful experience, deviating from this practice will create unit test code that is very tightly coupled to the internal implementation of a class’s dependencies.  A common culprit is the diabolical usage of the Singleton pattern (the authors of the GoF book are making a second version that will supposedly have a full section on Singleton abuse).  A frequent usage of a Singleton is to create a Repository object that manages the communication between a client and its backend services.  Since you cannot mock a Singleton (yeah I know you can do some IL magic, but do you really want to?), myself and many other people fall into the trap of attaching a mock for the backend data source classes into the Singleton instance and setting up the expectations on this mock.  Your unit test is basically validating that the calls that the class being unit tested makes to the repository causes another set of calls to a mock object that is standing in for the data service.  If the Singleton is in an unknown state or the internal caching mechanisms of the repository change, you will end up rewriting unit tests.

 

Since all I really wanted to test in this case was the interaction of a class with the repository class, I’m much better off writing a simpler test that mocks the repository directly.  Then I don’t have to worry about the state or the internals of the concrete implementation of the repository.

 

As long as you’re aware of the consequences of a Singleton or static members in general, it’s relatively simple to create a repository that doesn’t harm testability.  Here’s a couple of links on this specific issue:

 

 

Mock the Right Thing

 

Here’s an example of the single dumbest thing I’ve ever done with mock objects (and also an example of how NOT to do Model View Presenter).  We were building a WinForms application with somewhat complex workflow between the screens.  Each screen had some logic in the Presenter (Controller) class that determined whether or not the screen could be closed, usually by checking if the data on the screen was “dirty.”  To simulate a view with dirty data, we did something like the following:

 

      [TestFixture]

      public class PresenterTester

      {

            [Test]

            public void CloseViewWhenViewIsNotDirty()

            {

                  // Create the mock objects

                  IMock msgBoxMock = new DynamicMock(typeof(IMessageBoxCreator));

                  IMock viewMock = new DynamicMock(typeof(IView));

 

                  // Define the expected interaction

                  msgBoxMock.ExpectNoCall("AskYesNoQuestion", typeof(string), typeof(string));

                 

                  // Setup the view so that the controller will think the screen is dirty

                  viewMock.SetupResult("Name", "Jeremy");

                  viewMock.SetupResult("PhoneNumber", "SOMETHING DIFFERENT TO MAKE THE SCREEN DIRTY");

                  viewMock.SetupResult("Email", "jeremy@somewhere.com");

                  viewMock.SetupResult("State", "TX");

                  viewMock.SetupResult("PostalCode", "78750");

 

                 

                 

                  viewMock.Expect("Close");

 

                  Model model = new Model("Jeremy", "555-555-5555", "jeremy@somewhere.com", "TX", "78750");

 

                  // Create the presenter class with the mock objects

                  Presenter presenter = new Presenter(

                        model,

                        (IView) viewMock.MockInstance,

                        (IMessageBoxCreator) msgBoxMock.MockInstance);

 

                  // Perform the unit of work

                  presenter.Close();

 

                  // Verify the interaction

                  msgBoxMock.Verify();

                  viewMock.Verify();

            }

      }

 

This is a terrible unit test.  The “dirty” state of the view was tested by comparing the value of each property on the view class compared to the same property on the internal Model member of the Presenter class.  The unit tests setup “clean” or “dirty” states by setting up results for every single property on the IView interface.  In practice this obfuscated the intention of the unit tests and made the unit tests more laborious to write and maintain.  Everytime you added a new field to the screen, all the Presenter unit tests would break. 

 

In this case, isolate the “dirty” check so it can be tested separately from the screen flow logic.  What I do now is put an IsDirty() method on the view interface.  In the Presenter unit tests I simply setup a value for IsDirty() to easily simulate all of the paths through the code. 

 

            [Test]

            public void CloseViewWhenViewIsNotDirty()

            {

                  // Create the mock objects

                  IMock msgBoxMock = new DynamicMock(typeof(IMessageBoxCreator));

                  IMock viewMock = new DynamicMock(typeof(IView));

 

                  // Define the expected interaction

                  msgBoxMock.ExpectNoCall("AskYesNoQuestion", typeof(string), typeof(string));

 

                  // Very simply set the screen to be in a "clean" state

                  viewMock.ExpectAndReturn("IsDirty", false);

                  viewMock.Expect("Close");

 

                  // Create the presenter class with the mock objects

                  Presenter presenter = new Presenter(

                        (IView) viewMock.MockInstance,

                        (IMessageBoxCreator) msgBoxMock.MockInstance);

 

                  // Perform the unit of work

                  presenter.Close();

 

                  // Verify the interaction

                  _msgBoxMock.Verify();

                  _viewMock.Verify();

            }

 

 Now we’ve got a lot less mock setup and the unit tests will be less brittle and easier to understand because we’ve eliminated a lot of the noise from the view property setup. 

 

Watch Out When You Mock Abstract Classes

 

I would urge a certain level of caution in mocking an abstract class or a concrete class.  For best results my advice is to only mock interfaces to avoid unwanted side effects.  It is certainly possible to mock an abstract class, doing that leads to some side effects that effectively negate all of the advantages of a mock object.  Dynamic mock object tools like NMock can only override virtual methods.  This might not be so much a problem in other languages, but with the .Net languages all methods are non-virtual by default.  This means that some of the behavior that you were trying to remove from the test with a mock is still there.  The dynamic mock libraries work by using Reflection.Emit to create a dynamic proxy on the fly for the requested interface or abstract class.  In the case of an abstract class the dynamic mock can only intercept virtual members and even worse, the constructor function of the superclass will probably be exercised.  Here’s an example of mocking an abstract class that’s caused me some grief in the past.

 

      public abstract class ServiceProvider

      {

            public ServiceProvider()

            {

                  // Connect to a web service to cache some data

            }

 

            public abstract void PerformService();

 

            // Cannot be intercepted by a mock object because it's non-virtual

            public DataSet LookupData(string id)

            {

                  return new DataSet();

            }

      }

 

 

      [TestFixture]

      public class MockExampleTestFixture

      {

            [Test]

            public void TestSomething()

            {

                  // As soon as this code is executed the constructor function of

                  // ServiceProvider will be called

                  DynamicMock mock = new DynamicMock(typeof(ServiceProvider));

            }

      }

 

When you try to create a mock for ServiceProvider the abstract class is trying to access a web service in its constructor function.  If the web service isn’t available, the unit test blows up.  Even with the mock object, your unit test is now using the web service, making an implicit dependency between your unit test and an external resource and effectively eliminating the advantage of using a mock object in the first place.  The solution is might be simple; look for an opportunity to do an Extract Interface refactoring to create an IServiceProvider interface that can be mocked without any side effects.



Comments

Jeremy D. Miller said:

Geert,

Thanks for the comment, and yes I do like that solution. I do something similar now, but just put the equivialent of the IsDirtyStrategy embedded into the view class.
# January 11, 2006 7:16 AM

Geert Baeyaert said:

So, it doesn't bother you that the logic for determining whether a view is dirty is in the view?

How do you test this logic?
# January 11, 2006 8:23 AM

Jeremy D. Miller said:

Let me amend that a little bit, I still like to move that to a separate "controller" class that can be tested against a mock of the view like you were suggesting, I just embed that controller inside the view class to keep the view interface cleaner. I don't like that logic in the view class itself, unless you implement it by catching "Change" events. It's ugly, but you always have the ability to do some testing against the UI itself

public class View : IView, IScreenView (different interface for the properties)
{
private IDirtyStrategy _dirtyStrategy;

public bool IsDirty()
{
return _dirtyStrategy.IsDirty(this);

}

}

Another way I've been doing things with my little side UI projects is make every single field element on the screen implement some kind of IPropertyEditor object that has Reset(), Commit(), and IsDirty() methods. The controller can then iterate through the aggregated IPropertyEditor objects to make the "IsDirty" decision and drive data back and forth between the model and the screen. At least in WinForms development you can quite happily instantiate TextBox and ComboBox objects inside your unit tests without going through NUnitForms or some other sort of UI test harness.
# January 11, 2006 8:37 AM

Geert Baeyaert said:

Ok, I understand now. Thanks for clearing that up.
# January 11, 2006 10:38 AM

Jeremy D. Miller -- The Shade Tree Developer said:

A friend of mine was asking me a while back about ways to apply the Model View Presenter (the “Humble...
# February 1, 2006 11:18 PM

Jeremy D. Miller -- The Shade Tree Developer said:

Author: <a href="blogs/jeremy.miller/">Jeremy D. Miller</a><br />A friend of mine was asking me a while back about ways to apply the Model View Presenter (the “Humble Dialog Box”) pattern to ASP.Net development to promote easier unit testing of the user interface layer. Two weeks and a major case of writer’s block later, I finally finished the post. I wrote a blog post last spring describing the usage of MVP (“The Humble Dialog Box”) with WinForms clients, but web development in general and ASP.Net in specific comes with a different set of challenges.
# February 2, 2006 7:11 PM

Jeremy D. Miller -- The Shade Tree Developer said:

I had a question today about whether you could just mark methods as virtual on a concrete class so they...
# February 20, 2006 1:49 PM

vorpal.cc » Link Dump said:

# April 16, 2006 4:13 PM

Jeremy D. Miller -- The Shade Tree Developer said:

This was originally meant to be an example in the Test Small Before Testing Big post.  Several months...
# June 25, 2006 10:04 AM

Jeremy D. Miller -- The Shade Tree Developer said:

Between being extremely short handed at work, tech' reviewing a new book, a
possible book proposal...
# August 7, 2006 4:51 PM

Jeremy D. Miller -- The Shade Tree Developer said:

Between being extremely short handed at work, tech' reviewing a new book, a possible book proposal

# September 1, 2006 2:33 PM

Jeremy D. Miller -- The Shade Tree Developer said:

Jay Kimble , CodeBetter's resident AJAX guru, issued a little challenge to us TDD bloggers about using

# March 7, 2007 2:06 PM

Dim Blog As New ThoughtStream(me) said:

Jeremy Miller has posted quite a response to a question asked by Jay Kimble on unit testing with the...

# March 7, 2007 5:05 PM

Chad Myers' Blog said:

Starting a new set of projects, what to do?

# October 29, 2007 3:59 PM

Jeremy D. Miller -- The Shade Tree Developer said:

Author: Jeremy D. Miller A friend of mine was asking me a while back about ways to apply the Model View Presenter (the “Humble Dialog Box”) pattern to ASP.Net development to promote easier unit testing of the user interface layer. Two weeks and a major

# November 8, 2007 7:48 AM

Jeremy D. Miller -- The Shade Tree Developer said:

I'm not a particularly good tennis player. Mostly from not having played in years, but even then

# March 3, 2008 8:05 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Jeremy D. Miller

Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy previously worked as a systems architect building mission critical supply chain software for a Fortune 100 company and learned agile development practices as a .Net consultant at ThoughtWorks, one of the pioneers of agile development. Jeremy is the author of the open source StructureMap (http://structuremap.sourceforge.net) tool for Dependency Injection with .Net and the forthcoming StoryTeller (http://storyteller.tigris.org) tool for supercharged FIT testing in .Net. Jeremy's thoughts on just about everything software related can be found on his weblog "The Shade Tree Developer" at http://codebetter.com/blogs/jeremy.miller, part of the popular CodeBetter site. Jeremy is a Microsoft MVP for C#. Check out Devlicio.us!

This Blog

Syndication

News

All opinions expressed here constitute my (Jeremy D. Miller's) personal opinion, and do not necessarily represent the opinion of any other organization or person, including (but not limited to) my fellow employees, my employer, its clients or their agents.

About Me

"Best Of" Compendium

StructureMap (Dependency Injection for .Net)

StoryTeller (Supercharged Fit)

Build your own Cab

TestDriven

MVP