Mock Static Methods with Mockito

Learn to mock the static methods using Mockito in unit testing in Java. Previously, we had to use PowerMock to mock private and static methods, but starting version 3.4.0, Mockito supports mocking static methods directly. Read getting started with Mockito guide for setup instructions.

1. Maven Dependency

To mock static methods, we need to use the inline mock-making facility provided by mockito-inline module. Note that this module is separate from mockito-core module for some time, and in a future release it will be merged with mockito-core itself.

The mockito-inline module has been developed separately for community feedback and provides the mocking capability for static methods; and final classes and methods which previously were considered unmockable. It uses a combination of both Java instrumentation API and sub-classing rather than creating a new class to represent a mock.

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

2. System Under Test

For demo purposes, we are creating a simple class with two methods.

  • The first method does not take any argument and returns the string value “foo”.
  • The second method takes a variable number of int arguments and returns their sum.
class ClassWithStaticMethod {

  public static String getVal() {
    return "foo";
  }

  public static int add(int... args) {
    return IntStream.of(args).sum();
  }
}

3. MockedStatic class

The MockedStatic represents an active and scoped mock of a type’s static methods. Due to the defined scope of the static mock, it returns to its original behavior once the scope is released. To define mock behavior and to verify static method invocations, use the MockedStatic reference returned from the Mockito.mockStatic() method.

It is necessary to call ScopedMock.close() method to release the static mock once it has been used and is no longer needed. It is therefore recommended to create this object within a try-with-resources statement unless when managed explicitly.

The following is the syntax to use the MockedStatic class in a unit test.

try (MockedStatic mock = mockStatic(AppStatic.class)) {
  //record mock expectations
  //test code
  //verify mock
}

If we do not use try-with-resources block, as suggested, the mocking/stubbing/verifying will work as expected but leaves the class in a mocked state.

3. Mocking No-Args Static Methods

Let us mock the first method getVal() that takes no arguments and returns a String value "foo". We are mocking the getVal() method and returning the value "bar" from the mock.

When we invoke the getVal() method, outside the mock scope, we should the value as “bar” and inside the scope, we should get the value “foo”.

@Test
public void testGetVal() {
	//Outside scope
  assertEquals("foo", ClassWithStaticMethod.getVal());

  try (MockedStatic mockStatic = mockStatic(ClassWithStaticMethod.class)) {

    mockStatic.when(ClassWithStaticMethod::getVal).thenReturn("bar");

    //Inside scope
    assertEquals("bar", ClassWithStaticMethod.getVal());
    mockStatic.verify(ClassWithStaticMethod::getVal);
  }

  //Outside scope
  assertEquals("foo", ClassWithStaticMethod.getVal());
}

4. Mocking a Static Method with Arguments

Mocking the static methods that accept arguments and return values is pretty much same as the previous section. Additionally, we can use flexible argument-matchers in expectations.

Note that we are using the lambda expression syntax for invoking the static method.

@Test
public void testAdd() {
  assertEquals(3, ClassWithStaticMethod.add(1, 2));

  try (MockedStatic mockStatic = mockStatic(ClassWithStaticMethod.class)) {

    mockStatic.when(() -> ClassWithStaticMethod.add(anyInt(), anyInt())).thenReturn(10);

    assertEquals(10, ClassWithStaticMethod.add(1, 2));
    mockStatic.verify(() -> ClassWithStaticMethod.add(1, 2));
  }

  assertEquals(3, ClassWithStaticMethod.add(1, 2));
}

5. Conclusion

In this tutorial, we learned to create, record expectations and verify the mocks have static methods. Make sure you understand the fact that a static mock is expected to be used in a defined scope, and the module mockito-inline can be merged with mockito-core in the future.

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