我们暴露了一小组环境变量来控制我们的应用程序行为。应用程序代码在java中。 (环境变量可能是邪恶的,但在这种特殊情况下有目的)
对此进行单元测试的最佳方法是什么?如何创建环境变量,将其设置为不同的值并重复调用测试?
目前的解决方案是在junit任务中使用env元素。例如下面
<env key="BASE_PLUGINS_FOLDER" value="c:/temp"/>
代码为测试设置环境变量。 (仅当fork模式设置为true时才有效)
这意味着我必须在ant构建文件中创建多个测试部分,并在其他地方测试相应的测试部分。这可能会很快变得无法管理。
我觉得可能有更好的方法,那就是完整的junit-java代码。不确定如何。
答案 0 :(得分:8)
您应该封装检索这些变量的方式。它不仅允许您更改传递方式(env变量,系统属性,配置文件等等),而且还可以更加可测试。
然后,您可以定义两个不同的实现:一个实际读取环境(您在生产中使用),另一个您可以在Java中自己指定这些值(在测试中使用)。
答案 1 :(得分:3)
这是我朋友给的黑客..
Class<?> processEnvironmentClass = Class.forName("java.lang.ProcessEnvironment");
Field theEnvironmentField = processEnvironmentClass.getDeclaredField("theCaseInsensitiveEnvironment");
theEnvironmentField.setAccessible(true);
@SuppressWarnings({"unchecked"}) // this will be a Map or the test will fail if Java internals are changed
Map<String, String> env = (Map<String, String>) theEnvironmentField.get(null);
env.put(name, val);
// now System.getenv will return what we want
//noinspection CallToSystemGetenv
assertEquals("Problems setting up environment variable for test: " + name, val, System.getenv(name));
答案 2 :(得分:1)
我担心这是一个无用的,令人沮丧的答案......但考虑重新设计应用程序以允许覆盖环境变量。
所有对它们的访问都需要通过一个地方汇集,这也可以寻找您选择的配置机制 -
-D,
或财产档案,
或-d,
指向的属性文件
或测试设置传递的运行时创建的配置对象,
或烟雾信号,
或者......
答案 3 :(得分:0)
这可以使用 JUnit 4 和 JUnit 5 中的系统存根 (https://github.com/webcompere/system-stubs) 解决:
JUnit 4:
@Rule
public EnvironmentVariablesRule env = new EnvironmentVariablesRule("BASE_PLUGINS_FOLDER", "/tmp/something");
@Test
public void test() {
// variable is set here
}
或者在 JUnit 5 中:
@ExtendWith(SystemStubsExtension.class)
class SomeTest {
@SystemStub
private EnvironmentVariables env = new EnvironmentVariables("BASE_PLUGINS_FOLDER", "/tmp/something");
@Test
void envSetHere() {
// environment variable is set
}
}