Mockito

Mockito Initmocks Example

In this example we will learn how to initialize mocks in 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 frameworks 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 ‘MockitoInitmocks’.

Figure 1. Create a Java Project
Figure 1. Create a 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
Figure 2. New Java Package

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. Init Mocks

There are various ways how we can initialize the mocks.

3.1 Using Mockito.mock()

The first option is to use mock() method of org.mockito.Mockito class. For this example we will mock the java.util.LinkedList class.

LinkedList mocklinkedList = Mockito.mock(LinkedList.class);

The mock() method is used to creates mock object of given class or interface. By default, for all methods that return a value, a mock will return either null, a primitive/primitive wrapper value, or an empty collection, as appropriate. For example 0 for an int/Integer and false for a boolean/Boolean. Now we will define the expectation of the get() method as below:

Mockito.when(mocklinkedList.get(0)).thenReturn("First Value");

when() enables stubbing methods. Use it when you want the mock to return particular value when particular method is called. when() is a successor of deprecated Mockito.stub(Object). Stubbing can be overridden: for example common stubbing can go to fixture setup but the test methods can override it. Please note that overridding stubbing is a potential code smell that points out too much stubbing.

Once stubbed, the method will always return stubbed value regardless of how many times it is called. Last stubbing is more important – when you stubbed the same method with the same arguments many times. Although it is possible to verify a stubbed invocation, usually it’s just redundant. Now we will do the verification as below:

Assert.assertEquals("First Value", mocklinkedList.get(0));
Mockito.verify(mocklinkedList).get(0);

Below is the snippet of whole test method

@Test
public void testMock() {
  // Mock
  LinkedList mocklinkedList = Mockito.mock(LinkedList.class);
  // Stub
  Mockito.when(mocklinkedList.get(0)).thenReturn("First Value");
  // Verify
  Assert.assertEquals("First Value", mocklinkedList.get(0));
  Mockito.verify(mocklinkedList).get(0);
}

3.2 MockitoAnnotations initMocks()

We can initialize mock by calling initMocks() method of org.mockito.MockitoAnnotations

MockitoAnnotations.initMocks(this);

This initializes objects annotated with Mockito annotations for given testClass. This method is useful when you have a lot of mocks to inject. It minimizes repetitive mock creation code, makes the test class more readable and makes the verification error easier to read because the field name is used to identify the mock.

@Test
public void testFindById() {
  MockitoAnnotations.initMocks(this);
  MyService myService = new MyService(myDao);
  myService.findById(1L);
  Mockito.verify(myDao);
}

initMocks() is generally called in @Before (JUnit4) method of test’s base class. For JUnit3 initMocks() can go to setup() method of a base class. You can also put initMocks() in your JUnit runner (@RunWith) or use built-in runner:

3.2.1 Inject Mocks

Mark a field on which injection should be performed. It allows shorthand mock and spy injection and minimizes repetitive 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.

  1. 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.
    Note: 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.
  2. 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.
    Note: 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.
  3. 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.
    Note: 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.

3.3 MockitoJUnitRunner

Another way to initialize mocks is to use @RunWith(org.mockito.runners.MockitoJUnitRunner.class) annotation at the test class level. This is compatible with JUNit 4.4 and higher. It initializes mocks annotated with @MockMockitoJUnitRunner so that explicit usage of MockitoAnnotations.initMocks(Object) is not necessary. Mocks are initialized before each test method.

It validates framework usage after each test method. Runner is completely optional – there are other ways you can get Mock working, for example by writing a base class. Explicitly validating framework usage is also optional because it is triggered automatically by Mockito every time you use the framework.

MyServiceJUnitRunnerTest.java

package com.javacodegeeks;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class MyServiceJUnitRunnerTest {

  private MyService myService;
  @Mock private MyDao myDao;

  @Test
  public void testFindById() {
    myService = new MyService(myDao);
    myService.findById(1L);
    Mockito.verify(myDao).findById(1L);
  }
}

3.4 MockitoRule

Another way of initializing the mocks is to use the org.mockito.junit.MockitoRule class. You first annotate the class reference which needs to be mocked with @Mock annotation:

@Mock private MyDao myDao;

Then you define the rule as below:

@Rule public MockitoRule rule = MockitoJUnit.rule();

It initializes mocks annotates with @Mock so that explicit usage of org.mockito.MockitoAnnotations#initMocks(Object) is not necessary. Mocks are initialized before each test method. It validates framework usage after each test method.

MyServiceRuleTest.java

package com.javacodegeeks;

import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

public class MyServiceRuleTest {

  @Mock private MyDao myDao;

  @Rule public MockitoRule rule = MockitoJUnit.rule();

  @Test
  public void test() {
    MyService myService = new MyService(myDao);
    Mockito.when(myDao.findById(1L)).thenReturn(createTestEntity());
    MyEntity actual = myService.findById(1L);
    Assert.assertEquals("My first name", actual.getFirstName());
    Assert.assertEquals("My surname", actual.getSurname());
    Mockito.verify(myDao).findById(1L);
  }

  private MyEntity createTestEntity() {
    MyEntity myEntity = new MyEntity();
    myEntity.setFirstName("My first name");
    myEntity.setSurname("My surname");
    return myEntity;
  }

}

4. Download the source file

In this example we saw the various methods of initializing mock objects.

Download
You can download the full source code of this example here: MockitoInitmocks

Mohammad Meraj Zia

Senior Java Developer
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button