Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Junit5 mock a static method

Tags:

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?

like image 421
Priya Avatar asked Oct 16 '18 07:10

Priya


People also ask

Can you mock a static method?

Since static method belongs to the class, there is no way in Mockito to mock static methods. However, we can use PowerMock along with Mockito framework to mock static methods.

How do you mock static factory method?

Imagine you have a class called Option , like in scala. You can't avoid using a static factory method if you want to reuse same instance for all absent values. As soon as you go new Option(null) you create a new option object, you cannot return the same object over and over again. Similar use case is the Integer.

How do I use Powermock with JUnit 5?

To include powermock in our application, add the powermock-api-mockito2 and powermock-module-junit4 dependencies. Note that there is no official extension for JUnit 5. If you plan to use its reflection module, for example invoking the private methods, then we need to import powermock-reflect module as well.

Can I mock static class in unit test?

You can use Moq to mock non-static methods but it cannot be used to mock static methods. Although static methods cannot be mocked easily, there are a few ways to mock static methods. You can take advantage of the Moles or Fakes framework from Microsoft to mock static method calls.


1 Answers

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"));     } } 
like image 197
angelcervera Avatar answered Sep 20 '22 15:09

angelcervera