Introduction to Mockito when,thenReturn,Mock and InjectMocks-example by mocking database  operations

Mockito when-we use the Mockito when static method to mock a method’s behavior when it’s called. It is like saying when this method is called, I want you to do xyz to mock its functioning instead of actually doing the actual task its programmed to do. We shall see this clearly as we work on the below example.The mock task  is done by the thenReturn method whereby we can return a dummy(mocked) result vs the case whereby the actual method would have executed to return a result.

Other ways of mocking the result include;

  1. Mocking throwing of exception via thenThrow method
  2. Actually calling the real method via thenCallRealMethod
  3. Manipulating the returned result at runtime via thenAnswer method

Example-the SubjectServiceTests class

Our test class is as below

package com.school.relationships;

 

import com.school.relationships.entities.Subject;

import com.school.relationships.models.SubjectModel;

import com.school.relationships.repositories.SubjectRepository;

import com.school.relationships.services.SubjectService;

import lombok.extern.slf4j.Slf4j;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.mockito.InjectMocks;

import org.mockito.Mock;

import org.mockito.Mockito;

import org.mockito.junit.MockitoJUnitRunner;

 

@RunWith(MockitoJUnitRunner.class)

@Slf4j

public class SubjectServiceTests {

   

    @Mock

    private SubjectRepository subjectRepository;

    @InjectMocks

    SubjectService subjectService;

   

    @Test

    public void testCreateSubjectSuccessful() {

        log.info("Started testing method testCreateSubject");

        Mockito.when(subjectRepository.save(Mockito.any(Subject.class))).thenReturn(Mockito.mock(Subject.class));

         

        SubjectModel mockSubjectModel = new SubjectModel();

        mockSubjectModel.setSubjectName("Math");

        subjectService.createSubject(mockSubjectModel);

        log.info("Finished testing method testCreateSubject");

    }   

}

Understanding the above code:

  1. We bootstrap our test class by annotating it with @RunWith(MockitoJUnitRunner.class).This enables us achieve a number of tasks such as
  • It intializes Mocks annotated with @Mock hence assisting us to avoid using the static method initMocks.We shall discuss more of @Mock shortly.
  • Helps in detecting unused stubs in the test code.If we have stubs that are not used,our code will not build because we get the exception UnnecessaryStubbingException because anyway,why stub what we aren’t using?
  1. We use Lombok annotation @Slf4j for logging.
  2. We declare our class as public class SubjectServiceTests .The class name ends with Tests so that it’s included as test by the maven sure fire plug in.For more on this check https://maven.apache.org/surefire/maven-surefire-plugin/examples/inclusion-exclusion.html.
  3. We mock the SubjectRepository interface by annotating it with @Mock annotation.We can then control the behavior of this interface which handles CRUD operations for our Subject entities.
  4. We inject the mocked class above to the SubjectService instance which needs it by using the @InjectMocks annotation.
  5. Our test method is annotated with @Test.
  6. We mock the behavior of the repositories save method so that when any StudentModel is passed we mock a save(INSERT)operation and return a mocked saved Student Object.
  7. When our test case executes successfully without errors,our code coverage increases and we can also see the portion of code tested so far.

Test execution results

In our example, we see our code coverage rises from 0% to 1% as below.

before the testcase(at 0%)

 

after the testcase(at 1%)

 

We can go deeper in the report to the class we tested,the SubjectService class.

 

From the above,we can see our class is 75% tested.Let’s go deeper in the report .

 

We can see that we tested the success path,the happy path only.We now need to write a test case for a scenario that will throw an Exception while  creating a subject so that we can achieve 100% code coverage for this class and continue improving our overall code coverage score for the project.This is by using the thenThrow mockito method which we tackle in the next tutorial.

See Mockito thenThrow tutorial.

The code for this project at this stage is available at Github.

About the Author - John Kyalo Mbindyo(Bsc Computer Science) is a Senior Application Developer currently working at NCBA Bank Group,Nairobi- Kenya.He is passionate about making programming tutorials and sharing his knowledge with other software engineers across the globe. You can learn more about him and follow him on  Github.