Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring boot mocking static methods with PowerMock in Integration test

I'm writing integration test on a RestController in SpringBoot. Normally I would run with SpringRunner.class, but when it comes to Mock a static method I need to use PowerMock.

The strange fact is that when I run the single tests, they individually pass (but returns error messages), when I try to run the entire test class, no test passes and it returns the same error message.

@RunWith(PowerMockRunner.class)
@PrepareForTest({JwtUtils.class})
//@PowerMockRunnerDelegate(SpringRunner.class) THIS DOESN'T WORK!!!
@SpringBootTest(classes = SpringBootJwtApplication.class)
public class RestAccessIntegrationTest {

  @Autowired @InjectMocks
  RestController restController;

  @Mock
  HttpServletRequest request;

  @Test
  public void operationsPerAccountWhenSuccessfulTest(){
    mockStatic(JwtUtils.class);
    when(JwtUtils.myMethod(request)).thenReturn("blabla");
    String expected = ... ;
    String actual = restController.getOperations();
    assertEquals(actual, expected);
  }

}

If I run the test or the entire class I get an error of this type:

Exception in thread "main" java.lang.NoSuchMethodError: org.powermock.core.MockRepository.addAfterMethodRunner(Ljava/lang/Runnable;)at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:50)

If I uncomment @PowerMockRunnerDelegate(SpringRunner.class) there it comes this other error:

Exception in thread "main" java.lang.NoClassDefFoundError: org/powermock/core/testlisteners/GlobalNotificationBuildSupport$Callback at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner.run(DelegatingPowerMockRunner.java:139)

like image 976
Alex Mawashi Avatar asked Feb 24 '26 14:02

Alex Mawashi


2 Answers

In the when method, try using any(HttpServletRequest.class) instead of the request mock object. Also use MockHttpServletRequest instead of mocking HttpServletRequest. This should work,

@RunWith(PowerMockRunner.class)
@PrepareForTest(JwtUtils.class)
@PowerMockIgnore( {"javax.management.*"})
public class RestAccessIntegrationTest {

    @InjectMocks
    private RestController restController;

    private MockHttpServletRequest request;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        request = new MockHttpServletRequest();
        RequestContextHolder.setRequestAttributes(
                new ServletRequestAttributes(request));
    }

    @Test
    public void operationsPerAccountWhenSuccessfulTest() {
        mockStatic(JwtUtils.class);
        when(JwtUtils.myMethod(any(HttpServletRequest.class)))
           .thenReturn("blabla");

        String expected = ... ;
        // does your getOperations take HttpServletRequest
        // as parameter, then controller.getOperations(request);
        String actual = restController.getOperations();
        assertEquals(actual, expected);
    }
}
like image 58
Indra Basak Avatar answered Feb 27 '26 03:02

Indra Basak


It was due to incompatibility in library version of PowerMock and Mockito. I suggest to check the compatibility version table provided by PowerMock team or to switch to JMockit to mock static and private methods.

like image 23
Alex Mawashi Avatar answered Feb 27 '26 05:02

Alex Mawashi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!