Mockito: 3 Ways to Init Mock in JUnit 4

Initialize Mockito mock objects in JUnit 4 using MockitoJUnitRunner, MockitoAnnotations#initMocks, or Mockito#mock.

Overview

lang: en Update: a new post is available as “3 Ways to Init Mock in JUnit 5”.

Today, I will share with you three different ways to initialize mock objects in JUnit 4:

  • MockitoJUnitRunner
  • MockitoAnnotations#initMocks
  • Mockito#mock

I will share not only the source code, but also their advantage and inconvenience. I’m using JUnit 4 with Mockito 2.28.2.

Prerequisites

To use the core features of Mockito 2, you need to import the following dependency into your Maven project:

<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>2.28.2</version>
  <scope>test</scope>
</dependency>

MockitoJUnitRunner

Mock objects can be created using Mockito JUnit Runner (MockitoJUnitRunner). This runner is compatible with JUnit 4.4 and higher, this runner adds the following behavior:

  • Initializes mocks annotated with @Mock, so that explicit usage of MockitoAnnotations#initMocks(Object) is not necessary. Mocks are initialized before each test method.
  • Validates framework usage after each test method. See the Javadoc of Mockito#validateMockitoUsage()

Here’s an example of how you can use it:

@RunWith(MockitoJUnitRunner.class)
public class BookReaderAnnotationWithRunnerTest {

  @Mock
  private Book mockedBook;

  private BookReader reader;

  @Before
  public void setUp() {
    reader = new BookReader(mockedBook);
  }

  @Test
  public void testGetContent() {
    when(mockedBook.getContent()).thenReturn("Mockito");
    assertEquals("Mockito", reader.getContent());
  }
}

Pros:

  • Not need for explicit MockitoAnnotations#initMocks(Object)
  • Validates framework usage after each test method
  • Declarative thanks to @Mock annotation
  • Easy to read

Cons:

  • Annotation @RunWith can only be used once. This is not a repeatable annotation. Using @MockitoJUnitRunner means you cannot use other runners anymore.

MockitoAnnotations.initMocks

Mock objects can be initialized using Mockito annotation @Mock and MockitoAnnotations#initMocks(Object).

// no JUnit runner
public class BookReaderAnnotationWithSetupTest {

  @Mock
  private Book mockedBook;

  private BookReader reader;

  @Before
  public void setUp() {
    MockitoAnnotations.initMocks(this);
    reader = new BookReader(mockedBook);
  }

  @Test
  public void testGetContent() {
    when(mockedBook.getContent()).thenReturn("Mockito");
    assertEquals("Mockito", reader.getContent());
  }
}

Pros:

  • Declarative thanks to @Mock annotation
  • Easy to read

Cons:

  • Missing framework-usage validation after each test

Mockito.mock

Create mock object of given class or interface using Mockito#mock(Class<T> classToMock) or its overloaded methods.

public class BookReaderClassicMockTest {

  private BookReader reader;
  private Book mockedBook;

  @Before
  public void setUp() {
    mockedBook = Mockito.mock(Book.class);
    reader = new BookReader(mockedBook);
  }

  @Test
  public void testGetContent() {
    when(mockedBook.getContent()).thenReturn("Mockito");
    assertEquals("Mockito", reader.getContent());
  }

Pros:

  • More control on the mock you need to create

Cons:

  • More verbose
  • Less declarative

Going Further

How to go further from here?

You may also be interested in other Mockito articles that I wrote, they are available under /tags/mockito.

Conclusion

Today, I share 3 different ways to initialize mock objects in JUnit 4, using Mockito JUnit Runner (MockitoJUnitRunner), Mockito Annations (MockitoAnnotation#initMocks), and the traditional Mockito#mock. The source code of the examples above are available on GitHub mincong-h/java-examples. Interested to know more? You can subscribe to the feed of my blog, follow me on Twitter or GitHub. Hope you enjoy this article, see you the next time!

References