Legacy Coderetreat: Part 9 – Use Mocking Framework

Use Mocking Framework

Blog post series

This blog post is part of a series about legacy coderetreat and legacy code techniques you can apply during your work. Please click to see more sessions about legacy code.

Purpose

By using mocking frameworks we are writing short and easy to read tests. The duplication of test doubles written by hand is minimized by the use mocking framework.

mocking-framework

Concept

During the previous blog post we broke a static dependency by using extract and override. In this way we made the system testable.

The code above is in fact a test double called a test spy. Spying is a method of “stealing” information from a structure with the purpose of testing it or another collaborator.

But test spies are overcomplicating the production and the test code. This is why we want to keep the above step as an intermediary step. The next and final step of this refactoring of the production system is to use mocking framework. The purpose of the refactoring was to make the system testable, but as a result we also have a system with less coupling. But we need to minimize the coupling even more.

In order to minimize the coupling we need to start injecting the static dependencies. The principle of Dependency Inversion tells us that high level modules should not depend on low level modules. Writing to console is a lower level module than computing a sum.

So the function add should not depend on writing to console. Further more, the class Math should not depend on a console. At most the class Math should be able to collaborate with a generic message transmitter, a console being one possible implementation.

Step 1: Create interface and extract the implementation for our case

Step 2: Implement the interface for our case

Step 3: Use dependency injection to send the interface to the production class

(optional) Step 4: Try injecting other type of implementation

Because we separated the responsibilities of computing the sum and messaging,  we make our system a lot more flexible. We can change the console now with some other type of implementation. We could use this for example:

The system now is loosely coupled and more cohesive. The class Math has only one responsibility: compute a sum. The class Console has only one responsibility: write a message to the console. So we went from a Math class not respecting the Single Responsibility Principle to distributing the responsibilities to two classes: Math and Console. This change was made because we wanted to test the system. So trying to make a system testable improves the design of the system, by making it mode cohesive and loosely coupled.

Step 5: Write tests with the mocking framework

Now we need to change the tests as well. For this we typically use mocking framework. My choice is Mockito for Java, Mockito for Javascript, Moq for NUnit, GoogleMock for C++ and PHPUnit for PHP. In the code below I will use Mockito on Java.

In the code above we are injecting to the Math class the collaborator IMessage. But the IMessage instance is not a real production class, but what we call a test double. In this case the test double is called a mock. A mock is a test double that verifies method calls. The verify statement from this test basically says: check that when calling math.add(3,4) the math.add(3,4) method will call the IMessage instance with the parameter “The result is 7”.

Step 6: Remove temporary class from “Extract and Override”

In this moment we do not need the MathForTests class anymore. It was just a temporary step towards a better system design and simple test.

Outcomes

We started from having a class Math that had two responsibilities. The code still had some coupling between two structures: Math and Console. Because the Console was static, the dependency was extremely tight and made the system very hard to test.

We ended up with a code that detaches the two responsibilities. A code that is flexible to change, that respects the Single Responsibility Principle and which is easy to test.

Remarks

As an heuristic, if we can easily use a mocking framework on a system, it means that the system has a good design. If the tests are small with light setup, then usually the system has a flexible design.

Breaking static dependencies makes the system easier to change. Any static dependency means tight coupling thus an inflexible system. So we need to be extremely careful when we use static.

When testing existing systems, we should look first where we have static dependencies and statements that create instances directly from the code. Those are the places where we need to introduce abstractions in order to make the system testable.

Always new abstractions come with a cost. The fact that we introduced IMessage means that the system has more concepts and it’s harder to understand. But the benefits of having a testable system weigh a lot more. We always need to put into balance the costs of new concepts and abstractions and the benefits of a testable system. Each situation is different and we need to take a pragmatic decision, and never an emotional one.

History

Mocking started to exist in the early 90s. In the beginning mocks, stubs, spies, fakes and dummies were written by hand. Starting with late 90s mocking frameworks started to appear on the market. In the beginning they were not so mature and were difficult to use. Now we can say that most of the mocking frameworks are easy to use and provide a real help to minimize the effort to write testing code. When searching for a mocking framework try to see pros and cons of each one on the market, and select the one that is easy to use and understand.

Code Cast

Please find here a code cast in Java about this session

Subscribe

If you want to receive an email when I write a new article, subscribe here:

Subscribe for new articles

Leave a Reply

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

Post Navigation