Spring boot mocking static methods with PowerMock in Integration test
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);
}
}
Related videos on Youtube
Alessandro Argentieri
Software architect and IT instructor, specialized in complex microservice environments and cloud native.
Updated on June 04, 2022Comments
-
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 over 6 yearsAre you still using
@SpringBootTest(classes = SpringBootJwtApplication.class)
? I didn't get any exception when I don't use it. -
Alessandro Argentieri over 6 yearsI'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.