If you’ve been writing unit tests for a short while you might have noticed that writing good unit tests is hard. The object under test can be hard to create because it require dependencies that you just cannot provide or some complicated environment is needed just to make the test pass.
When writing a unit test one of the challenges is how to code around the dependencies of the object of his test. In other words – how to isolate the code under test from external dependencies.
Fake, Stubs and Mocks
There is a difference – at least for some people – between mocks, stubs and fakes. for the purpose of this post and every unit test you will ever write – it does not really matters.
Some mocking framework have the distinction between these types of objects and for the sake of terminology (which some people seem to like) I’ll explain the difference between the two:
- Stubs are used to replace an object that your object depends on
- Mocks are used to verify that happened to that object (while faking some, all or none of it’s calls)
In a nutshell you do not care what happens to the stub during the test, but you do want to know something about the interaction between objects when you’re using a mock.
For a short (and good) explanation of mocks take a look at Roy Osherove’s mock objects elevator speech.
I prefer to simply call them “fakes”, because unless the tool I’m using forces me to differentiate between them – I don’t really care what they are as long as I write a good unit test.
When to use Fake objects
If you need to simulate the behavior of a complex or hard to create object – use fake object.
There are other good reasons for faking an object:
- Make the test deterministic – unit tests should have the same result each time you run them. If your object returns a non deterministic value that would change each time you run the test, by faking that class behavior you can make it return the same value each and every time.
- Hard to set up environment – if you need a database (with specific data), a server or similar components for the test to pass.
- When objects do not yet exist – during development you cannot rely on all of the objects you need to be when you need them. You might need another class that was not written yet or some algorithm that was not implemented yet.
- Difficult to reproduce state – e.c. you need to check what happens when your client receives a network error while calling its server.
Fake objects are used to isolate your code from external dependencies. You can write your own (called hand rolled mocks/fakes) but there is no reason to reinvent the wheel – there are isolation frameworks for most mainstream languages – check Wikipedia’s list of mock object frameworks for your language of choice.
What Isolation framework can do for you?
All isolation (Mocking) frameworks I came across do the following three:
- Create fake objects
- Set fake object’s behavior
- Verify method was/wasn’t called
Some frameworks have additional capabilities – depending on the programming language their internal operation (how they work).
In the following posts I will explain about each of the three above – along with code examples!