SoFunction
Updated on 2025-04-09

How to mock static method problem of Mockito

How to mock static method of Mockito

In actual work, we often encounter situations where we need to mock static methods. In the era of mockito, we need to use powmock to achieve it.

After mockito evolved to version 3.4.0, it also began to support the static method mock (mainly through the mockito-inline package).

This is the brief introduction, let’s get to the topic below.

1. First make sure that the pom file is in

The version of the mockito-related jar package (the version I use here is 3.7.7), as follows:

<dependency>
    <groupId></groupId>
    <artifactId>mockito-core</artifactId>
    <version>3.7.7</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId></groupId>
    <artifactId>mockito-inline</artifactId>
    <version>3.7.7</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId></groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>3.7.7</version>
    <scope>test</scope>
</dependency>
<dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
     <version>4.13</version>
     <scope>test</scope>
 </dependency>

2. How to use

(Class mockClass),as follows:

// Here static methods are provided in DateUtilMockedStatic&lt;DateUtil&gt; dateUtil = mockStatic();

Example:

import static ;

@RunWith()
public class AlphaServiceTest {

    @Test
    public void testHttp() {
        ...
        
        MockedStatic&lt;HTTPClient&gt; httpClient = mockStatic();
        (() -&gt; ("xxx/zzz/ccc", "hello")).thenReturn("success");
        
        ...
        
        // closure        ();
    }
    

This is basically OK.

The only thing to note is (), this problem will be explained in "3. Others" in "Error prompt static mocking is already registered in the current thread To create a new mock, the existing static mock registration must be deregistered")

3. Others

If mockito-inline is not introduced into the project, the following error message will appear:


The used MockMaker SubclassByteBuddyMockMaker does not support the creation of static mocks

Mockito's inline mock maker supports static mocks based on the Instrumentation API.
You can simply enable this mock mode, by placing the 'mockito-inline' artifact where you are currently using 'mockito-core'.
Note that Mockito's inline mock maker is not supported on Android.

    at .testSaveClinicalFreeSuccess1(:86)
    at .invoke0(Native Method)
    at (:62)
    at (:43)
    at (:498)
    at $(:50)
    at (:12)
    at (:47)
    at (:17)
    at .(:74)
    at .(:84)
    at .(:75)
    at .(:86)
    at .(:84)
    at (:325)
    at .junit4.(:251)
    at .junit4.(:97)
    at $(:290)
    at $(:71)
    at (:288)
    at $000(:58)
    at $(:268)
    at .(:61)
    at .(:70)
    at (:363)
    at .junit4.(:190)
    at (:137)
    at .junit4.(:68)
    at $(:33)
    at (:230)
    at (:58)

Error message

static mocking is already registered in the current thread To create a new mock, the existing static mock registration must be deregistered

When multiple unit tests use the same static mock object, and no close is performed after use. At this time, if these unit tests are executed together, the first unit test occupies the static mock object, and the second unit test has no way to occupy it.

If this happens, the solution is also very simple, which is to close the static mock object, as follows:

import static ;

@RunWith()
public class AlphaServiceTest {

    @Test
    public void testHttp1() {
        ...
        
        MockedStatic<HTTPClient> httpClient = mockStatic();
        (() -> ("xxx/zzz/ccc", "hello")).thenReturn("success");
        
        ...

		();
    }
    
    @Test
    public void testHttp2() {
        ...
        
        MockedStatic<HTTPClient> httpClient = mockStatic();
        (() -> ("xxx/zzz/ccc", "hello")).thenReturn("success");
        
        ...

		();
    }
    
    @Test
    public void testHttp3() {
        ...
        
        MockedStatic<HTTPClient> httpClient = mockStatic();
        (() -> ("xxx/zzz/ccc", "hello")).thenReturn("success");
        
        ...
		
		();
    }

If you use mockStatic() in many of your unit tests and think that writing mockStatic()…close() is very inefficient, you can use the following method:

import static ;

@RunWith()
public class AlphaServiceTest {
	private MockedStatic&lt;HttpClietn&gt; httpClient;

	// Before each unit test is started, execute this method first (@Before was replaced with @BeforeEach in the higher version)    @Before
    public void setUp() {
         = mockStatic();
    }
    
	// After each unit test is executed, execute this method (@After is replaced with @AfterEach in the higher version)    @After
    public void teardown() {
        ();
    }

    @Test
    public void testHttp1() {
        ...
        
        (() -&gt; ("xxx/zzz/ccc", "hello")).thenReturn("success");
        
        ...
    }
    
    @Test
    public void testHttp2() {
        ...
        
        (() -&gt; ("xxx/zzz/ccc", "hello")).thenReturn("success");
        
        ...
    }
    
    @Test
    public void testHttp3() {
        ...
        
        (() -&gt; ("xxx/zzz/ccc", "hello")).thenReturn("success");
        
        ...
    }

This makes it much more refreshing ~ :)

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.