Using PowerMock in Spring JUnit Test


Unit testing with help of a mocking framework has been recognized as a useful practice for a long time and the Mockito framework.


First of all we need to configure and add related two dependency in order to use powermock.

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>1.6.4</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito</artifactId>
    <version>1.6.4</version>
    <scope>test</scope>
</dependency>

Lets assume spring bean like this.

@Component
public class MyBeanClass{
    public SendingMessage startProcessMyBeanClass(){
        final long id = IdGenerator.generateNewId();
        return new SendingMessage(id, "startProcessMyBeanClass started, and my class
        bean was generated")
    }
}

And if we want to test startProcessMyBeanClass method, in this test we assume that it's important for us to mock static call to IdGenerator.generateNewId(). However in order to run the test as spring integration test. we need to use SpringJunit4ClassRunner which prevents us from using the PowerMockRunner.

@RunWith(SpringJunit4ClassRunner.class)
@ContextConfiguration("classpath:/example-context.xml)
@PrepareForTest(IdGenerator.class) //the class where static method exist
public class MyBeanClassTest{
    @Rule
    public PowerMockRule rule = new PowerMockRule();

    @Autowired
    private MyBeanClass classBean;

    @Test
    public void mockStaticMethod() throws Exception{
        // Given
        final long expectedId = 2L;
        mockStatic(IdGenerator.class);
        when(IdGenerator.generateNewId()).thenReturn(expectedId);

        // When
        final SendingMessage message = classBean.startProcessMyBeanClass();

        // thenReturn
        assertEquals(expectedId, message.getId());
        assertEquals("startProcessMyBeanClass started, and my class
        bean was generated, message.content());
    }
}

In main aim to use PowerMock is that the static methods can be tested in unit test. There is a sample which points the one controller in spring.

@WebAppConfiguration
@EnableWebMvc
@SpringJUnitConfig(classes=MainController.class)
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringJunit4ClassRunner.class)
@PowerMockIgnore("javax.management.*)
//to specify that all classes under the specified package be loaded by the system class loader
@PrepareForTest({TestService.class,TestRandomService.class ...})
//points the classes having the static methods
public class MyBeanClassTest{
    @MockBean
    public TestService testService;

    private static final String userName = "burak kilinc";

    //it can be used for static methods as generic
    private void mockGetUtilService(){
         //assume account service
        GenericAccountService accountService = new GenericAccountService();
         //assume user service
        GenericUserService userService = new GenericUserService();
        PowerMockito.mockStatic(TestService.class);
        PowerMockito.mockStatic(TestRandomService.class);
        //when
        PowerMockito.when(TestService.get(Mockiton.anyString())).thenReturn(accountService);
    }
}