Getting Started With Mockito and JUnit

In this Mockito tutorial, learn the fundamentals of the mockito framework, and how to write JUnit tests along with mockito with an example.

@ExtendWith(MockitoExtension.class)
public class ItemServiceTest {

  @Mock
  private ItemRepository itemRepository;

  @InjectMocks
  private ItemService itemService; // Assuming ItemService uses ItemRepository

  @Test
  public void testCreateItem() {
      
      // ...
    }
}

1. Introduction to Mockito

Mockito is an open-source framework that allows us to create test doubles (mocks) easily. A ‘test double‘ is a generic term for any case where we replace a production object for testing purposes.

In mockito, we generally work with the following kinds of test doubles.

  • Stubs – are objects that have predefined return values to the method executions made during the test.
  • Spies – are objects that are similar to stubs, but they additionally record the stats of how they were executed.
  • Mocks – are objects that have return values to method executions made during the test and has recorded expectations of these executions. Mocks can throw an exception if they receive a call they don’t expect and are checked during verification to ensure they got all the calls they were expecting.

We can mock both interfaces and classes in the test class. Mockito also helps to produce minimum boilerplate code if we use the using mockito annotations.

Once created, a mock will remember all interactions. Then we can selectively verify whatever interactions we are interested in.

2. Mockito Setup with JUnit

2.1. Maven

To add mockito to the project, we can add the latest mockito version by any means i.e. Maven, Gradle or Jar file.

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>5.4.0</version>
    <scope>test</scope>
</dependency>
testCompile group: 'org.mockito', name: 'mockito-core', version: '4.6.1'

2.2. Bootstrapping with JUnit 5

Add the Junit Jupiter dependency for using mockito with JUnit 5.

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.10.0</version>
    <scope>test</scope>
</dependency>

To process Mockito annotations with JUnit 5, we need to use MockitoExtention as follows:

@ExtendWith(MockitoExtension.class)
public class ApplicationTest {
   //code
}

2.2. Bootstrapping with JUnit 4 [Legacy]

Add the Junit 4 dependency for using mockito with JUnit 4.

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>

For legacy JUnit 4, we can use either MockitoJUnitRunner or MockitoRule classes.

@RunWith(MockitoJUnitRunner.class)
public class ApplicationTest {
	//code
}
@RunWith(MockitoJUnitRunner.class)
public class ApplicationTest {

  @Rule 
  public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);

  //code
}

The strict stubbing ensures clean tests, reduces test code duplication, and improves debuggability. The test fails early when the code under test invokes a stubbed method with different arguments, or unused stubs are present.

2.3. Programmatic Initialization

Alternatively, we can programmatically bootstrap mockito using openMocks() method somewhere in the base class or a test runner. This method initializes fields annotated with Mockito annotations @Mock, @Spy, @Captor, @InjectMocks.

The previously used initMocks() method is now deprecated.

@BeforeEach
public void setup() {

  MockitoAnnotations.openMocks(this);
}

3. Mockito Annotations

Before hitting the keyboard to write unit tests, let’s quickly go through the useful mockito annotations.

  • @Mock is used for mock creation. It makes the test class more readable.
  • @Spy is used to create a spy instance. We can use it instead spy(Object) method.
  • @InjectMocks is used to instantiate the tested object automatically and inject all the @Mock or @Spy annotated field dependencies into it (if applicable). It is worth knowing the difference between @Mock and @InitMocks annotations.
  • @Captor is used to create an argument captor.
public class ApplicationTest {

  @Mock
  Depedency mock;

  @InjectMocks
  Service codeUnderTest;
}

4. Mockito Demo

4.1. System Under Test

To demo the Mockito syntax, we have created a typical usecase where a RecordService invokes RecordDao to save a Record.

The RecordService uses a SequenceGenerator class to get the next record id.

4.2. Test Demo

  • To test RecordService.saveRecord() method, we need to inject RecordDao and SequenceGenerator as dependencies in it. For this, we are using @Mock and @InjectMocks annotations.
  • The @ExtendWith(MockitoExtension.class) starts the bootstrapping process and injects the mocks into the service instance.
  • We use the when(…).then(…) methods to record the expectations from mock objects, and we verify these expectations, after the application code execution finishes, using the verify() method calls.
  • Finally, we can use additional JUnit assertions for additional validations, if any.
@ExtendWith(MockitoExtension.class)
public class MockitoHelloTest {

  @Mock
  RecordDao mockDao;

  @Mock
  NotificationService mockNotification;

  @Mock
  SequenceGenerator mockGenerator;

  @InjectMocks
  RecordService service;

  @Test
  public void testSaveRecord() {

    Record record = new Record();
    record.setName("Test Record");

    when(mockGenerator.getNext()).thenReturn(100L);
    when(mockDao.saveRecord(record)).thenReturn(record);

    Record savedRecord = service.saveRecord(record);

    verify(mockGenerator, times(1)).getNext();
    verify(mockDao, times(1)).saveRecord(any(Record.class));

    assertEquals("Test Record", savedRecord.getName());
    assertEquals(100L, savedRecord.getId());
  }
}

5. Conclusion

In this Mockito JUnit tutorial, we learned the basics of mocking and stubbing using the mockito framework. We learned to bootstrap the mocking process in JUnit 4 and 5 environments.

Finally, we saw an example of a test using mockito and junit.

Happy Learning !!

Sourcecode on Github

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode