Mocking using Mockito

Mocking static methods

Since version 3.4.0 Mockito has provided the capability to mock static method invocations (AKA static mocking).

The Mockito.mockStatic method is the entrypoint for the mocking of class objects and their static methods. In the example below the public static method Currency.getInstance is mocked:

  @Test
  public void testCurrency() {
    Currency usd = Currency.getInstance("USD");
    try (MockedStatic<Currency> mockedStatic = mockStatic(Currency.class)) {
      mockedStatic.when(() -> Currency.getInstance(anyString())).thenReturn(usd);

      Currency eur = Currency.getInstance("EUR");
      assertEquals("USD", eur.getCurrencyCode());
      mockedStatic.verify(() -> Currency.getInstance(anyString()));
    }
  }

As you can see, the API for static mocks is slightly different from that used for creating instance mocks. It is also recommended to execute static mocks within a try-with-resources statement.

Configuration

Static mocking is only available if the inline mock maker is enabled in your project. Since version 5.0.0 of Mockito, the inline mock maker is the default and no action is needed. For prior versions of Mockito, instead of using the mockito-core artifact, include the mockito-inline artifact in your project to enable the inline mock maker. The example below shows detail from a Maven pom.xml:

    <dependency>
      <groupId>org.mockito</groupId>
      <!--<artifactId>mockito-core</artifactId>-->
      <artifactId>mockito-inline</artifactId>
      <version>4.6.1</version>
      <scope>test</scope>
    </dependency>

Usage

To support the mocking of static methods the --mock-static option has been added to Diffblue Cover. This allows the user to suggest the names of classes whose static methods should be mocked when unit testing. Diffblue Cover will mock the static methods of these suggested classes, and if those mocks prove valuable for test coverage they will be included in the resulting tests.

For example, in the example command line below, the user is suggesting that it might be of utility to mock both the Foo class and the Bar class when creating tests for the class FooBarUser:

dcover create com.diffblue.FooBarUser --mock-static=com.diffblue.Foo,com.diffblue.Bar

Diffblue Cover will issue warnings if the --mock-static option is used in a project which does not support static mocking - it will ignore the option and continue with test creation.

Caveat

The inline mock maker is an optional feature of Mockito before version 5.0.0.

Mockito includes this note in the JavaDoc for Mockito.mockStatic.

Note: We recommend against mocking static methods of classes in the standard library or classes used by custom class loaders used to executed the block with the mocked class. A mock maker might forbid mocking static methods of know [sic] classes that are known to cause problems. Also, if a static method is a JVM-intrinsic, it cannot typically be mocked even if not explicitly forbidden.

The error messages issued by Mockito.mockStatic can be broad and confusing. The static mocking of low-level standard library classes can be unreliable and have unpredictable effects. It may take some experimentation to fine-tune use of this powerful feature.

Mocking constructors

Since version 3.5.0 Mockito has provided the capability to mock constructor method invocations.

The mockConstruction method is the entrypoint for the mocking of constructors. In the example below the Date constructor is mocked:

  public static long currentTime() {
    return new Date().getTime();
  }

  @Test
  public void testCurrentTime() {
    // Arrange
    try (MockedConstruction<Date> dateMocked = mockConstruction(Date.class, (mock, context) -> {
      when(mock.getTime()).thenReturn(1_000_000_000_000L);
    })) {
      // Act
      final long time = currentTime();
      // Assert
      Assertions.assertEquals(1_000_000_000_000L, time);
    }
  }

As you can see, the API for mocked construction is different from that used for creating instance mocks. Similar to static mocking, it is recommended to mock constructors within a try-with-resources statement.

Configuration

Construction mocking is only available if the inline mock maker is enabled in your project. To enable it, instead of using the mockito-core artifact, include the mockito-inline artifact in your project. The example below shows a detail from a Maven pom.xml:

    <dependency>
      <groupId>org.mockito</groupId>
      <!--<artifactId>mockito-core</artifactId>-->
      <artifactId>mockito-inline</artifactId>
      <version>4.11.0</version>
      <scope>test</scope>
    </dependency>

Usage

To support the mocking of constructors the --mock-construction option has been added to Diffblue Cover. This allows the user to suggest the names of classes whose constructors should be mocked when unit testing. Diffblue Cover will mock the constructors of these suggested classes, and if those mocks prove valuable for test coverage they will be included in the resulting tests.

For example, in the example command line below, the user is suggesting that it may be useful to mock both the Foo constructors and the Bar constructors when creating tests for the class FooBarUser:

dcover create com.diffblue.FooBarUser --mock-construction=com.diffblue.Foo,com.diffblue.Bar

Diffblue Cover will issue warnings if the --mock-construction option is used in a project which does not support mocked construction - it will ignore the option and continue with test creation.

Last updated