Mocks, Fakes, and Stubs. What are they and when do I use them?

I know there has been tons of things already written about mock, fakes, and stubs available all over the Internet, but I’ve decided to add to that glut and give my spin on these wonderful testing ideas.  The first questions are: why should I care what the difference between the three is and how do I use them?  Well, I’m glad you asked those questions because, it’s really quite simple.  You use mocks, fakes, and stubs during unit testing such that you can test a small section of code in a safe manner without requiring the entire system to be instantiated to run the test.  Depending on how and what you are going to test determines which of the three methodologies you’ll use.

Now, this is all well and good, but let’s define the three methodologies.  I tend to feel Martin Fowler gives the definitions that I agree with the most, so I’ll use those:

Mock objects pre-programmed with expectations which form a specification of the calls they are expected to receive.

Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production.

Stub objects provide canned answers to calls made during the test, usually not responding at all to anything outside what’s programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it ‘sent’, or maybe only how many messages it ‘sent’.

I have a large preference for using fakes and stubs.  I’m not a huge fan of mocks since sometimes the coding gymnastics you do to get the mock behaving like you want, writing a fake could be written.  Also, mocks point to the fact, that you probably should have written an interface and implemented that instead of a single concrete implementation.  However, since I’m talking about all three of them, here are some examples on how I use each of them (and I can start with my least favorite one to get it out of the way).

Mock objects are best used when the the code being tested uses a library not under your control and you need to test very specific actions on the library.  For instance, you’ve written a wrapper to a database connector and you want to test to make sure that data read from the database is converted correctly.  In this case, I’d use a mock library (like Mockito in Java) to mock the calls to the database for the test harness.

Fakes, which are my favorite testing helper, can take the most work to get running, but they are far more flexible in my opinion once they are completed.  As described before, a fake is a working implementation of an interface that takes shortcuts in it’s implementation such that it behaves as the full implementation acts but without the overhead.  I find them most useful when testing database interactions with higher level code.  A good example of this is business logic in a server.  There is no reason to instantiate all the database layers in order to test the business logic.  It’s much easier to provide a fake implementation of the interface to the database and let the business logic do it’s thing.  In addition, these fake implementation can be used throughout your codebase anytime a database connection is needed.

Finally, there are stub objects.  Stub objects are meant to be used when only a small piece of functionality is used from a collaborating class within the codebase.  For instance, if there is a larger class being used, but only two simple methods are being used — a stub is more than likely a great choice.  Stub objects are often implemented as private inner classes to the test class such that all relevant code is kept close.    This old Spring Source blog article does a pretty good job of describing the difference between Mocks and Stubs.

In conclusion, these are three basic unit testing techniques and a quick overview of when to use each of them.  Personally, I find fakes to be the most helpful and reusable and mocks to be the least effective; however, different strokes for different folks (and codebases).  The bottom line is pick the best approach for the codebase and job at hand and test that code!

Leave a Reply

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