How to effectively incorporate mocking into your unit tests
Mocking is an important part of unit testing components with integrations and those that rely on external dependencies. But what exactly is it? In tests, mocking is using mock objects with fake business logic to replicate the function of a real object.
Mocks can produce better tests by reducing a factor that could cause the test to fail (e.g. needing to access an external resource like a database, which could be offline for reasons unrelated to your test) and helping you isolate the classes being tested. They can also save time and stop you from being charged for accessing these external resources.
Too much of a good thing?
Mocks are important to know how to use well, which means you have to really understand your code and its intended behavior; ideally, mocks are used only when necessary. However, new test writers sometimes go overboard, which runs the risk of slowing down tests and making them needlessly complicated. Using too many mocks can even affect whether you’re ultimately testing the right thing, e.g. testing that something is implemented in a specific way, rather than testing that the desired outcome occurs.
Here are some best practices for mocking to help you use this method as effectively as possible.
When isn’t mocking appropriate?
Mocks work best when the code being tested isn’t tightly coupled; decoupled code tends to result from Test Driven Development (TDD), which no doubt partially explains why mocking is encouraged in the TDD community. For tightly coupled code (as is often present in legacy code), it might be the case that two or more classes form one unit, which can still be tested with a unit test. If not, think about whether the paired class has a lot of its own logic and whether it matters to test it separately. If not, don’t write a mock for it.
Similarly, don’t mock value objects; there’s simply no reason to because they don’t have their own logic. Also avoid mocking concrete classes, because these trap you in a certain implementation of the class you’re mocking.
In some cases, different types of “test doubles” similar to mocks are more appropriate instead. For a more detailed discussion about the differences between and applications for mocks, stubs, fakes, dummies, and other test doubles, check out Martin Fowler’s classic article on the topic.
- Get your unit testing techniques in shape
- Choose a testing framework
- Choose a mocking framework
Which mocking framework is right for you?
You can write mocks manually, but a few open source mocking frameworks make it a lot faster and easier to maintain your mocks if you write tests frequently (which you should!).
Many mocking frameworks for Java code work in combination with JUnit and other popular unit testing frameworks, and are great depending on your specific needs. Two of the most widely used are Mockito and PowerMock. Mockito is useful for all but the most complicated cases, for which you can use PowerMock instead. Fortunately these frameworks are compatible with each other, so you can start in Mockito for most mocks and switch to PowerMock for the more complex cases.
Less is more
Remember, this powerful method only needs a light touch, and can help you write effective unit tests and clean, agile code. With the right tools and the careful application of these techniques, you’ll be mocking in style.