About Mohammad Meraj Zia

I did my Engineering in Information Technology from IET, Lucknow, India. Currently doing MSc in Information Technology from Derby University. I have worked in Java/J2EE domain for the last 10 years. Have good understanding of Payment and Finance domains.

Writing JUnit Test Cases Using Mockito

In this example we will learn how to write JUnit tests using Mockito. A unit test should test a class in isolation. Side effects from other classes or the system should be eliminated if possible. Mockito lets you write beautiful tests with a clean & simple API. Tools and technologies used in this example are Java 1.8, Eclipse Luna 4.4.2

1. Introduction

Mockito is a popular mocking framework which can be used in conjunction with JUnit. Mockito allows us to create and configure mock objects. Using Mockito simplifies the development of tests for classes with external dependencies significantly. We can create the mock objects manually or can use the mocking framewors like Mockito, EasyMock. jMock etc. Mock frameworks allow us to create mock objects at runtime and define their behavior. The classical example for a mock object is a data provider. In production a real database is used, but for testing a mock object simulates the database and ensures that the test conditions are always the same.

2. Creating a project

Below are the steps we need to take to create the project.

Open Eclipse. Go to File=>New=>Java Project. In the ‘Project name’ enter ‘MockitoJUnitExample’.

Figure 1. New Java Project

Eclipse will create a ‘src’ folder. Right click on the ‘src’ folder and choose New=>Package. In the ‘Name’ text-box enter ‘com.javacodegeeks’. Click ‘Finish’.

Figure 2. New Java Package

Right click on the package and choose New=>Class. Give the class name as JUnitMockitoExample. Click ‘Finish’. Eclipse will create a default class with the given name.

Figure 3. New Java Class

2.1 Dependencies

For this example we need the junit and mockito jars. These jars can be downloaded from Maven repository. We are using ‘junit-4.12.jar’ and ‘mockito-all-1.10.19.jar’. There are the latests (non-beta) versions available as per now. To add these jars in the classpath right click on the project and choose Build Path=>Configure Build Path. The click on the ‘Add External JARs’ button on the right hand side. Then go to the location where you have downloaded these jars. Then click ok.

3. Verify interactions

In this section we will see how we can verify the mock object interactions. We will make use of the java.util.Set interface for this. First we will create the mock Set by calling the org.mockito.Mockito.mock() method and passing the Set class to it as a parameter.

Set mockSet = mock(Set.class);

The mock() method creates mock object of given class or interface.

Now we will call two methods (addAll() and clear()) of the Set class on this mock object as shown below:

mockSet.addAll(toAdd);
mockSet.clear();

Now we will verify that these methods have been called

verify(mockSet).addAll(toAdd);
verify(mockSet).clear();

This verifies certain behavior happened once. Argument passed are compared using equals() method. Below is the snippet of the full method:

5. Spy

Spy is used for partial mocking. It creates a spy of the real object. The spy calls real methods unless they are stubbed. Real spies should be used carefully and occasionally, for example when dealing with legacy code. Sometimes it’s impossible or impractical to use when(Object) for stubbing spies. Therefore for spies it is recommended to always use doReturn|Answer|Throw()|CallRealMethod family of methods for stubbing.

Mockito does not delegate calls to the passed real instance, instead it actually creates a copy of it. So if you keep the real instance and interact with it, don’t expect the spied to be aware of those interaction and their effect on real instance state. The corollary is that when an *unstubbed* method is called *on the spy* but *not on the real instance*, you won’t see any effects on the real instance. Note that the spy won’t have any annotations of the spied type, because CGLIB won’t rewrite them. It may troublesome for code that rely on the spy to have these annotations.

6. InjectMocks

@InjectMock allows shorthand mock and spy injection. Mockito will try to inject mocks only either by constructor injection, setter injection, or property injection in order and as described below. If any of the following strategy fail, then Mockito won’t report failure; i.e. you will have to provide dependencies yourself.

Constructor injection: the biggest constructor is chosen, then arguments are resolved with mocks declared in the test only. If the object is successfully created with the constructor, then Mockito won’t try the other strategies. Mockito has decided to no corrupt an object if it has a parametered constructor. If arguments can not be found, then null is passed. If non-mockable types are wanted, then constructor injection won’t happen. In these cases, you will have to satisfy dependencies yourself.

Property setter injection: mocks will first be resolved by type (if a single type match injection will happen regardless of the name), then, if there is several property of the same type, by the match of the property name and the mock name. If you have properties with the same type (or same erasure), it’s better to name all @Mock annotated fields with the matching properties, otherwise Mockito might get confused and injection won’t happen. If @InjectMocks instance wasn’t initialized before and have a no-arg constructor, then it will be initialized with this constructor.

Field injection: mocks will first be resolved by type (if a single type match injection will happen regardless of the name), then, if there is several property of the same type, by the match of the field name and the mock name. If you have fields with the same type (or same erasure), it’s better to name all @Mock annotated fields with the matching fields, otherwise Mockito might get confused and injection won’t happen. If @InjectMocks instance wasn’t initialized before and have a no-arg constructor, then it will be initialized with this constructor.

Now we will see an example of this.
First we will create a domain class. This class represents the Report entity.

Now we will define out test class. In the test class we will will annotate the ReportGeneratorService class with @InjectMocks.

@InjectMocks private ReportGeneratorService reportGeneratorService;

The IReportGenerator class will be annotated with the @Mock annotation.

@Mock private IReportGenerator reportGenerator;

In the setup method we will initialize the mocks.

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}

7. Argument Matchers

Mockito verifies argument values in natural java style: by using an equals() method. Sometimes, when extra flexibility is required then you might use argument matchers. Argument matchers allow flexible verification or stubbing. If you are using argument matchers, all arguments have to be provided by matchers. Matcher methods like anyObject(), eq() do not return matchers. Internally, they record a matcher on a stack and return a dummy value (usually null). This implementation is due to static type safety imposed by the java compiler. The consequence is that you cannot use anyObject(), eq() methods outside of verified/stubbed method.

ArgumentCaptor is a special implementation of an argument matcher that captures argument values for further assertions:

Newsletter

Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

Email address:

Receive Java & Developer job alerts in your Area

Leave this field empty if you're human:

Join Us

With 1,240,600 monthly unique visitors and over 500 authors we are placed among the top Java related sites around. Constantly being on the lookout for partners; we encourage you to join us. So If you have a blog with unique and interesting content then you should check out our JCG partners program. You can also be a guest writer for Java Code Geeks and hone your writing skills!

Disclaimer

All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners. Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.