As a qualified development engineer, writing a good UT (Unit Test) is a necessary skill, and there are many UT tools on the market. I have chosen the most widely used combination of Mockito + Powermock to analyze its source code, and I hope it will bring you a rewarding experience.

Please note that this series will not introduce you to basic usage.

Before starting the series, let’s first agree on the version.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <scope>test</scope>
    <version>2.0.9</version>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito2</artifactId>
    <scope>test</scope>
    <version>2.0.9</version>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-reflect</artifactId>
    <scope>test</scope>
    <version>2.0.9</version>
</dependency>

As you can see above, I’m using powermock version 2.0.9, which integrates the junit + mockito framework.

Mock && InjectMocks && Spy

When I was first learning Mockito, I had some ambiguity about the meaning of Mock, InjectMocks, and Spy, so I’ll start by explaining them here.

After using Mock on a class. Then all member variables of that class will be set to their default values and all method implementations will be left empty for subsequent customization. As shown in the figure below, for class Order, its member variables are set to their default values, its method print() implementation is cleared, and the method returns its default value.

Spy, on the other hand, is the opposite of mock, it’s kind of like new, in that it constructs a class that gets its real member variables and methods.

If you have a class that you want to mock completely, and only implement some of the methods I use, then use mock; if you have a class that you want to mock only a small part of it, and the rest of it performs real logic, then use spy.

For InjectMocks, it creates an instance of the class, similar to Spy in this respect. In addition it will search for all mocks and spy, and if the class has references to these objects inside it, it will inject them in, kind of like an IOC container.

As shown above, when I use InjectMocks on OrderService, the mocked member variable OrderClient is automatically injected into it, and the OrderService method is called with the real logic.

Mock Principle

I don’t know if you’ve ever wondered how Mock can achieve such awesome functionality with just a few lines of code when you first encountered it, which is why I went to study its source code.

Simply put, when you mock, it creates a proxy class by way of a proxy. Later, when you stub whenThen, it will save all these stubs. When you really use it, the priority is to determine whether the stub exists as expected, and if it does, it returns the value, and if it doesn’t, it returns the default value or calls the real method, depending on the situation.

Does it sound quite simple, the next article will formally open the source code analysis part of it.