Mock System class with Mockito + PowerMock

In this post, I am going to show how to mock the System.getenv and System.getProperty methods.

I have used Mockito and PowerMock to do this. Make sure to include the below dependencies in your pom file.


      <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito</artifactId>
            <version>1.6.4</version>
            <scope>test</scope>
        </dependency>
        <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-common</artifactId>
            <version>1.6.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-core</artifactId>
            <version>1.6.4</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock.tests</groupId>
            <artifactId>powermock-tests-utils</artifactId>
            <version>1.6.4</version>
            <scope>test</scope>
        </dependency>
 

I have created an another util class which has the getEnv and getProperty methods. So instead of mocking the System class methods explicitly, I have mocked the MockUtils static methods.

MockUtils.java


package com;

import org.apache.commons.lang3.StringUtils;

public class MockUtils {

    public static String getEnv(String name) {
        return StringUtils.defaultIfBlank(System.getenv(name), "");
    }

    public static String getProperty(String name) {
        return StringUtils.defaultIfBlank(System.getProperty(name), "");
    }
}

Here is my test class.

MockTest.java



package com;

import com.MockUtils;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static junit.framework.Assert.assertEquals;

@RunWith(PowerMockRunner.class)
@PrepareForTest(MockUtils.class)
@PowerMockIgnore("javax.management.*")
public class MockTest {

    @BeforeClass
    public static void setupClass() throws Exception {
        PowerMockito.mockStatic(MockUtils.class);
        PowerMockito.when(MockUtils.getEnv("APP_ENV")).thenReturn("DEV");
        PowerMockito.when(MockUtils.getProperty("username")).thenReturn("bala");
    }

    @Test
    public void testMockUtils() {
        assertEquals("DEV", MockUtils.getEnv("APP_ENV"));
        assertEquals("bala", MockUtils.getProperty("username"));
    }
	

Sometimes the static method might be used in the underlying classes and if those classes are not using the mocked values, then you can initialize the mocked values in the @Before like below,


import static junit.framework.Assert.assertEquals;

@RunWith(PowerMockRunner.class)
@PrepareForTest(MockUtils.class)
@PowerMockIgnore("javax.management.*")
public class MockTest {

    @Before
    public void setupClass() throws Exception {
        PowerMockito.mockStatic(MockUtils.class);
        PowerMockito.when(MockUtils.getEnv("APP_ENV")).thenReturn("DEV");
        PowerMockito.when(MockUtils.getProperty("username")).thenReturn("bala");
    }

    @Test
    public void testMockUtils() {
        assertEquals("DEV", MockUtils.getEnv("APP_ENV"));
        assertEquals("bala", MockUtils.getProperty("username"));
    }
	

Advertisements