Spring boot mocking static methods with PowerMock in Integration test

12,062

Solution 1

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.

Solution 2

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);
    }
}
Share:
12,062

Related videos on Youtube

Alessandro Argentieri
Author by

Alessandro Argentieri

Software architect and IT instructor, specialized in complex microservice environments and cloud native.

Updated on June 04, 2022

Comments

  • Alessandro Argentieri
    Alessandro Argentieri almost 2 years

    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)

  • Indra Basak
    Indra Basak over 6 years
    Are you still using @SpringBootTest(classes = SpringBootJwtApplication.class)? I didn't get any exception when I don't use it.
  • Alessandro Argentieri
    Alessandro Argentieri over 6 years
    I've tried with and without... I've used all the instructions you gave me. The weird thing is that each single test works, the whole class not.