java – 如何在Junit PowerMockito中使用System.getenv

我能够从Junit模拟System.getenv值,但是当我执行测试用例时 – 在我的服务类System.getevn中,值为null.不知道我在这里做错了什么.请找我的测试服务类和junit类.

有些人可以帮我解决这个问题 – 为什么价值不在我的实际服务类中设置?

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() {

    }
}

最佳答案 仅仅因为PowerMockito允许我们模拟静态并不意味着我们应该这样做.

您的类依赖于静态实现问题,这些问题在大多数情况下使单元测试变得困难.

考虑遵循显式依赖原则

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

创建所需功能的抽象

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);
}

该实现将封装对静态系统类的实际调用

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);
    }
}

然后,您的依赖类将需要重构以包含抽象

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);
    }
}

现在进行测试,您可以根据需要模拟必要的依赖项,而不会产生任何负面影响然后,在调用实际代码时,将在生产中使用该实现.

最后我建议不要让你的构造函数抛出异常.构造函数应主要用于变量赋值.

点赞