Junit5 mock a static method
Solution 1
The short answer is no, as the Mockito team is done with their work and is waiting for the JUnit team for an extension and are discussing here a lot.
With some overhead you can: As JUnit 5 provides support for running legacy JUnit 4, and there you can use Mockito. So you can create tests in Junit4 for these cases:
A sample project for migration setup with gradle and with mvn. From there I am using PowerMock 2.0 beta with Mockito 2.
Solution 2
From Mockito 3.4.0 (2020-07-10), it is possible to mock static methods out of the box even in JUnit 5, without any extension.
In the documentation, you can find an example: 48. Mocking static methods (since 3.4.0)
Important note: You need to use inline mock maker. So the dependency to use is not the core one:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.4.6</version>
<scope>test</scope>
</dependency>
Example: Class under test:
package teststatics;
public class FooWithStatics {
public static Long noParameters() {
return System.currentTimeMillis();
}
public static String oneParameter(String param1) {
return param1.toUpperCase();
}
}
Test class:
package teststatics;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
public class FooWithStaticsTest {
@Test
void testStatic() {
// Before mock scope, usual behavior.
assertNotEquals(0L, FooWithStatics.noParameters());
assertNotEquals("yyy", FooWithStatics.oneParameter("xxx"));
// Mock scope
try (MockedStatic mocked = mockStatic(FooWithStatics.class)) {
// Mocking
mocked.when(FooWithStatics::noParameters).thenReturn(0L);
mocked.when(() -> FooWithStatics.oneParameter("xxx")).thenReturn("yyy");
// Mocked behavior
assertEquals(0L, FooWithStatics.noParameters());
assertEquals("yyy", FooWithStatics.oneParameter("xxx"));
// Verifying mocks.
mocked.verify(times(1), FooWithStatics::noParameters);
mocked.verify(times(1), () -> FooWithStatics.oneParameter("xxx"));
}
// After mock scope returns to usual behavior.
assertNotEquals(0L, FooWithStatics.noParameters());
assertNotEquals("yyy", FooWithStatics.oneParameter("xxx"));
}
}
Solution 3
The reason why Mockito doesn't provide static methods mocking at the moment is because of the common belief that static method shouldn't need to be mocked.
However, there is an open item for Mockito here that discusses the issue.
While this doesn't answer your question, in general it tells you why you shouldn't need the feature at all or will allow you to join the conversation with your ideas.
Solution 4
Make sure to have
mockito-inline
dependency in your POM file<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-inline</artifactId> <version>3.6.28</version> <scope>test</scope> </dependency>
In my case I had to test scenario where exception thrown static method
encode()
ofURLEncoder
Class, so for thattry (MockedStatic theMock = mockStatic(URLEncoder.class)) { theMock.when(() -> URLEncoder.encode("Test/11", StandardCharsets.UTF_8.toString())) .thenThrow(UnsupportedEncodingException.class); when(restClient.retrieveByName("Test%2F11")).thenReturn(null); Assertions.assertThrows(ResponseStatusException.class, ()->service.retrieveByName("Test/11")); }
Related videos on Youtube
Priya
Updated on January 28, 2022Comments
-
Priya over 2 years
I want to mock a static method in JUnit 5. But unfortunately, JUnit 5 doesn’t support Mockito. Is there another method to achieve the same other than reverting back to JUnit 4?
-
angelcervera almost 4 yearsFrom Mockito 3.4, it is possible to do it out of the box. Please, check my answer and example.
-
-
Yeikel almost 5 yearsA common scenario where this is needed is if we need to mock calls to System.getenv which I don't see it as a bad pattern necessarily. Please correct me if I am wrong
-
AR1 almost 5 years@Yeikel the scenario you mentioned should be handled by the UT framework, in fact it's possible to address it using Rules in JUnit4 or Extensions in JUnit5
-
AR1 almost 5 yearsIt's not supported out of the box, that's true, but there are smart ways to do it with extensions.
-
Yeikel almost 5 yearscould you please link me to any reference that talks about that? We are considering dowgrading to Junit4 just because this feature is missing..
-
AR1 almost 5 yearsYou don't need to downgrade. Worst case you can still using @rule called by an extension. I'll put together an example for you.
-
Gerold Broser almost 4 yearsSee also the answer to Why doesn't Mockito mock static methods? which links to the announcing blog post with a simple 3-steps example.
-
Raghavendra S S over 3 years@angelcervera Using mockedStatic how can I mock a static void method? I can't use the above instruction for a method that has void as a return type.
-
Xavier DSouza almost 3 years@angelcervera very helpful answer. I was struggling for a while and had to use jmockit to mock static methods, but this really simplified lot of my junit5 tests. Thank you :)
-
Alex over 2 yearsIt's work. Thanks so much