简体   繁体   中英

how to use System.getenv in Junit PowerMockito

I'm able to mock the System.getenv value from Junit but when I execute the test case - in my service class System.getevn value coming as null. Not sure what I'm doing wrong here. Please find my test service class and junit class.

Can some please help me to fix this issue - why the value is not setting in my actual service class?

TestService.java

public class TestService {

    public TestService() throws Exception {

        loadTestMethod();

    }

    private void loadTestMethod() {

        System.out.println("Environment vairlable : " + System.getenv("my_key_name"));
        System.setProperty("app.key", System.getenv("my_key_name"));

    }

}

TestServiceTest.java

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
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;

@RunWith(PowerMockRunner.class)
@PrepareForTest(value = { System.class })
@PowerMockIgnore("javax.management.*")

public class TestServiceTest {

    @Mock
    TestService testService;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);

        PowerMockito.mockStatic(System.class);
        PowerMockito.when(System.getenv("my_key_name")).thenReturn("Testing");
        System.out.println("Junit Environment vairlable : " + System.getenv("my_key_name"));
        testService = new TestService();

    }

    @Test
    public void myServiceTest() {

    }
}

Just because PowerMockito allows us to mock static does not mean that we should.

Your classes are dependent on static implementation concerns that make unit testing in isolation, in most cases, difficult.

Consider following the Explicit Dependency Principle

Methods and classes should explicitly require (typically through method parameters or constructor parameters) any collaborating objects they need in order to function correctly.

Create an abstraction of the desired functionality

public interface SystemWrapper {
    //The "standard" output stream
    PrintStream out;
    //Gets the value of the specified environment variable
    string getenv(string name);
    //Sets the system property indicated by the specified key.
    string setProperty(String key, String value);
}

The implementation will encapsulate the actual calls to the static system class

public class SystemWrapperImplementation implements SystemWrapper {
    //The "standard" output stream
    public final PrintStream out = System.out;

    //Gets the value of the specified environment variable
    public string getenv(string name) {
        return System.getenv(name);
    }

    //Sets the system property indicated by the specified key.
    public string setProperty(String key, String value) {
        return System.setProperty(key, value);
    }
}

Your dependent class will then need to be refactored to include the abstraction

public class TestService {
    private SystemWrapper system;

    public TestService(SystemWrapper system) throws Exception {
        this.system = system;
        string key = "app.key";
        string name = "my_key_name";
        loadTestMethod(key, name);
    }

    private void loadTestMethod(string key, string name) {
        string environmentVariable = system.getenv(name);
        system.out.println("Environment variable : " + environmentVariable);
        system.setProperty(key, environmentVariable);
    }
}

Now for testing you can mock the necessary dependencies as needed without any adverse effects. The implementation will then be used in production when invoking actual code.

Finally I would suggest not having your constructors throwing exceptions. Constructors should mainly be used for assignments of variables.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM