Table of Contents
In this lesson with Mockito, we will use another framework for complete testing, known as JUnit. According to JUnit website,
JUnit is a simple framework to write repeatable tests. It is an instance of the xUnit architecture for unit testing frameworks.
With Mockito, creating mock objects is very easy. It provides many simple annotations to do so. Internally, a mock is nothing but a proxy for the actual class instance.
Here are steps to create Mockito JUnit example.
Step 1:Â Create a simple java maven project.
Maven Dependency
Step 2: Add required dependencies to pom.xml
A Maven dependency is the fastest way to get started with Mockito:
1 2 3 4 5 6 7 8 |
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-all --> <dependency> Â Â Â <groupId>org.mockito</groupId> Â Â Â <artifactId>mockito-all</artifactId> Â Â Â <version>1.9.5</version> </dependency> |
Just a single dependency which doesn’t bring any other libraries with it. See here for latest versions of the library.
As we will also be using some JUnit functionality, we will also need it’s dependency. Let’s add it next,
1 2 3 4 5 6 7 8 |
<!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> Â Â Â <groupId>junit</groupId> Â Â Â <artifactId>junit</artifactId> Â Â Â <version>4.11</version> </dependency> |
Finally, we will also be using AssertJ.
1 2 3 4 5 6 7 8 |
<dependency> Â Â <groupId>org.assertj</groupId> Â Â <artifactId>assertj-core</artifactId> Â Â <version>3.6.2</version> Â Â <scope>test</scope> </dependency> |
Your pom.xml will look as below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.arpit.java2blog</groupId> <artifactId>MockitoJunitExample</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/org.mockito/mockito-all --> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.9.5</version> </dependency> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> <version>3.6.2</version> <scope>test</scope> </dependency> </dependencies> </project> |
Mockito and JUnit
The simplest way to get started easily is by showing an example.
Step 3: We will define an interface named as MathService. Here is our interface:
1 2 3 4 5 6 7 8 9 |
package org.arpit.java2blog.mockito; public interface MathService { long doubleLong(long num); long tripleLong(long num); long addition(long... nums); } |
Next, we will be adding its implementation. Clear enough, those will be simple mathematical implementations:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package org.arpit.java2blog.mockito; public class MathServiceImpl implements MathService { public long doubleLong(long num) { return 2 * num; } public long tripleLong(long num) { return 3 * num; } public long addition(long... nums) { int sum = 0; for (long a : nums) sum += a; return sum; } } |
What to do next?
Step 4: Let us focus on the steps we need to perform to get started with Mockito mocks:
- Annotate the test class with
@RunWith(MockitoJUnitRunner.class)
. - Annotate the test fields with either @Mock or @Spy annotation to have either a mock or spy object instantiated.
- Annotate the system under test with @InjectMocks annotation.
Let’s apply above three steps to provide our test demo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
package org.arpit.java2blog.mockito; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class JUnitTest { @Mock MathService mathService; @InjectMocks MathServiceImpl mathServiceImpl = new MathServiceImpl(); @Before public void setup() { MockitoAnnotations.initMocks(this); } @Test public void test_doubleLong_Pass() { long expected = 20; Mockito.when(mathService.doubleLong(Mockito.anyLong())).thenReturn(expected); long actual = mathService.doubleLong(Mockito.anyLong()); Assert.assertEquals(expected, actual); } @Test public void test_doubleLong_Inject() { long expected = 20; //this method is actually called long actual = mathServiceImpl.doubleLong(10); Assert.assertEquals(expected, actual); } } |
Now, it is worth noticing that when a Mock is used, the actual method implementation is not called. In the second test-case we wrote, the implementation of the method was actually called.
When you run above test, you will get below output:
Sometimes, the test case classes are already been annotated with a @RunWith
annotation and Mockito’s annotation won’t have any effect. In order to correct this, you have to call MockitoAnnotations.initMocks manually like,
1 2 3 4 5 6 7 8 9 10 11 12 |
@InjectMocks MeanCalculator systemUnderTest; @Before public void setup() { MockitoAnnotations.initMocks(this); } @Test … |
Mockito vs JUnit
JUnit is a framework that helps with writing and running your unit tests.
Mockito (or any other mocking tool) is a framework that you specifically use to efficiently write certain kind of tests.
The main objective to perform unit testing to isolate your class you want to test from anything else in your project and testing its functionality. To do that, we have to create "test doubles" that you provide to an object of your "class under test". We can create all those "test doubles" ourselves too, or you use a mocking framework that generates an object of a certain class for you using reflection techniques. Interestingly enough, some people ask to never use mocking frameworks but without them, we will be just reinventing the wheel, a bad one.
In other words: you can definitely use JUnit without using a mocking framework. Same is true for the reverse direction; but in reality, there are not many good reasons why you would want to use Mockito for anything else but unit testing.
@RunWith(MockitoJUnitRunner.class) vs MockitoAnnotations.initMocks(this)
Using MockitoJUnitRunner
 rather than JUnitRunner
 is really optional.
The main advantage provided byMockitoJUnitRunner is relieving you to explicitly invoke MockitoAnnotations.initMocks(Object) when you use the @Mock
way to create your mocks.
But you could also get a few more misuse reports of the Mockito framework by using this runner that may be missing without using it.
Example of incorrect uses that may be caught out of the box without using the MockitoJUnitRunner:
1 2 3 4 5 6 7 8 9 10 |
//Oops, thenReturn() part is missing: when(mock.get()); //Oops, verified method call is inside verify() where it should be on the outside: verify(mock.execute()); //Oops, missing method to verify: verify(mock); |
But these could not be caught in all cases.