An Absolute Beginner Guide to Mockito with Spring

Darryl Leong
4 min readOct 22, 2020

--

What is Mockito?

“Mockito is a mocking framework, JAVA-based library that is used for effective unit testing of JAVA applications.”. Thanks TutorialsPoint, but what exactly does this mean to you?

If you’re a developer, you probably understand the importance of testing in general. It’s the one ways to ensure the robustness of code as well as ensure that you’re able to weed out those unexpected pesky bugs — hence, one of the contributors to the rise in popularity of TDD (Test Driven Development).

So how does Mockito fit into this picture at all?

Well, Mockito creates dummy objects which can be used in the code we are testing. Take the following example —

Given the following 2 classes: (Square and Calculate)

// Square.java
@Component
public class Square {
public int calculateSquare(int num){
return num*num;
}
}
// Calculate.java
@Component
public class Calculate {
@Autowired
Square square;
public boolean calculateIsSquareEven(int a){
int aSquared = square.calculateSquare(a);
return aSquared % 2 == 0;
}
}

calculateIsSquareEven verifies whether the squared value of the provided integer is an even number. If we were to take a little closer look at calculateIsSquareEven, we will notice that it is calling calculateSquare within it.

This is where Mockito comes in. The purpose behind unit testing is to test only ONE unit of code, which is usually a method. If we were to write a simple unit test for calculateIsSquareEven right now (without Mockito), it might look something like this

@SpringBootTest
class CalculateTests {
@Autowired
Calculate calculate;
@Test
void calculateIsSquareEvenTest() {
boolean result = calculate.calculateIsSquareEven(2);
Assertions.assertTrue(result);
}
}

And if you ran this test, it would pass! So what is the problem here? Well if take a closer look, we realize that we testing 2 ‘units’ of code with this one test, the first being calculateIsSquareEven and the second being calculateSquare. While on the surface, there might not seem to be a problem (given this simplistic example), but it demonstrates the potential issue that could follow.

To illustrate this, let’s say the test had failed — as a developer would you know what the cause of the failure was? In this case, it would be rather easy to identify the source of the problem, it’s either an error in calculateIsSquareEven or calculateSquare. But in real world situations, with complex applications, its never as straightforward as this. Functions might have multiple dependencies, and those dependencies might have their own set of dependencies. Identifying the problem wouldn’t be so trivial anymore.

This is where Mockito comes in. Mockito ‘mocks’ dependencies within a unit of code being tested. This in turn helps to isolate the code being tested. That way, should the test fail, you would know exactly what went wrong and where.

@SpringBootTest
class CalculateTests {
@Mock
Square square;
@InjectMocks
Calculate calculate;
@Test
void mockitoCalculateIsSquareEvenTest() { Mockito.when(square.calculateSquare(Mockito.anyInt())).thenReturn(4;
boolean result = calculate.calculateIsSquareEven(2);
Assertions.assertTrue(result);
}
}

The above shows how Mockito is typically used in unit testing, there are 3 things to take note of:

  1. @Mock — this annotation is used to let Spring know which dependency requires a ‘mock’ of. In this case, since our main focus is testing calculateIsSquareEven in Calculate.java, we want to ‘mock’ Square. Theis annotation creates a shell of the instance it’s being applied to, while adding the ability to track method invocations from it.
  2. @InjectMocks — as the name suggests, this annotation is used to indicate the component which is going to utilize the Mock.
  3. Mockito.when(…).thenReturn(…) — the passed function is stubbed with the response provided.

Again, it is important to remember what Mockito allows us to do. It enables us to cleanly segment and test units of code in isolation without the worry of additional dependencies. That’s basically it! Well.. not entirely… now that you understand the idea behind Mockito and have seen it’s most common use case, lets take a look at 2 other commonly used features in the Mockito library.

  1. Mockito.spy
  2. Mockito.verify

Mockito.spy 🕵️‍♂️

Going back to the example above, In reality, our calculateSquare function isn’t going to be placed in a separate class from our calculateIsSquareEven. So we might end with a Calculate class which looks something like this:

@Component
public class Calculate {
@Autowired
Square square;
public boolean calculateIsSquareEven(int a){
int aSquared = square.calculateSquare(a);
return aSquared % 2 == 0;
}
public int calculateSquare(int num){
return num*num;
}
}

So the question that arises next is — How do we mock a method within the same class? Is that even possible? Of course it is! And it’s equally as simple with Mockito.spy.

@SpringBootTest
class CalculateTests {
@Autowired
Calculate calculate;
@Test
void calculateIsSquareEvenTest() {
Calculate nCalculate = Mockito.spy(calculate);
Mockito.when(nCalculate.calculateSquare(Mockito.anyInt())).thenReturn(4);
boolean result = calculate.calculateIsSquareEven(2);
Assertions.assertTrue(result);
}
}

What Mockito.spy is doing is creating what is known as a partial Mock. Unlike the earlier examples with @Mock which mocks the entire object, a partial Mock only stubs methods which are explicitly defined while everything else works the same.

Mockito.verify ✅

Mockito verify can be used to ensure that certain behaviours occured. It can be useful in situations where there is no return value (void) but the function resulted in some form of data manipulation elsewhere. In such cases and cases alike, verify can be a very powerful tool track the method behaviour.

@SpringBootTest
class CalculateTests {
@Autowired
Calculate calculate;
@Test
void updateRandomNumberTest(){
calculate = Mockito.spy(calculate);Mockito.when(calculate.calculateSquare(Mockito.anyInt())).thenReturn(4);
calculate.updateRandomNumber();
Mockito.verify(calculate, Mockito.times(1)).calculateSquare(Mockito.anyInt());
}
}

As you can see in the example above, verify is used to validate that the function calculateSquare was invoked once.

Conclusion

And.. that’s about it! As far as basics go. I hope that through this guide you were able to build a firm understanding of the motivations for Mockito as well as get an idea on how to use some of it’s more commonly used features. If you found this guide at all useful, please give it a Clap and share it if you loved it. I appreciate any thoughts and criticisms!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Darryl Leong
Darryl Leong

Written by Darryl Leong

I write sometimes because its fun

No responses yet

Write a response