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

标签 java junit mockito powermockito

我能够模拟来自 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);
    }
}

现在为了测试,您可以根据需要模拟必要的依赖关系,而不会产生任何不利影响。当调用实际代码时,该实现将在生产中使用。

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

关于java - 如何在 Junit PowerMockito 中使用 System.getenv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49477530/

相关文章:

java - 谷歌云消息开发者 Android 代码崩溃

grails - 是否可以在junit中启动grails服务器应用程序

java - 无法为 Junit 的方法创建模拟调用

java - Spring 2.0.0.RELEASE 中的 Mockito Bug

java - JAXB boolean 处理异常和 JSF

JavaFX CSS效果帮助(截图)

java - 无法在Android代码中的Alarm OnReceive方法上执行select.php

scala - 如何使用 Maven 插件通过 JUnit 测试运行 Scalatest

unit-testing - 检测提交的单元测试代码覆盖率

java - Mockito-需要帮助从示例中学习