我有一个仅使用System.getEnv
返回环境变量的类,并且我正在尝试为此编写JUnit测试,但是我总是得到null。
我正在尝试将application-test.yml
与所有变量一起使用,并尝试了许多注释,例如
@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(locations="classpath:/application-test.yml")
和许多其他方法,但仍然没有成功。有谁知道如何简单地做到这一点?
答案 0 :(得分:1)
有多种方法。
选项1
如果在IDE(Eclipse或IntelliJ IDEA)中运行测试,则可以在IDE中设置测试变量。如果您使用的是maven,则可以通过Surefire插件-https://maven.apache.org/surefire/maven-surefire-plugin/examples/system-properties.html
设置系统属性。<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<systemProperties>
<property>
<name>buildDir</name>
<value>${project.build.outputDirectory}</value>
</property>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>
选项2
使用Spring EL
"classpath:config_#{systemProperties['env']}/db.properties"
更多详细信息可以在这里找到-how to read System environment variable in Spring applicationContext
答案 1 :(得分:0)
Spring与环境变量无关。它可以读取它们,但据我所知,它不会说任何东西,与系统属性不同。
环境变量本应存在于环境中。
因此,您有以下选择:
选项1
使用Power Mock,它可以模拟出静态方法调用。该库不是spring的一部分,因此您可以在测试范围内使用它,以免对生产产生影响(powermock jar将不在生产依赖项列表中)
选项2
用一些外部类包装静态调用,然后使用常规的模拟框架对其进行模拟/或加载相同接口的不同bean,因为无论如何您都在使用Spring Test。该代码将如下所示:
interface EnvAccessor {
String getValue(String envVarName);
}
public class MyEnvAccessor {
String getValue(String envVarName) {
return System.getenv(envVarName);
}
}
选项3
除了在JUnit测试开始之前以编程方式设置env变量外,在生产代码中什么都不做:
public class SampleTest {
@BeforeClass
public static void setupEnvironment() {
// set the environment here
}
}
现在,特别是从测试和一般从Java代码设置环境非常棘手,因为不应通过编程方式更改环境变量。
您可以阅读Here有关可能的解决方法的信息,并在程序中对其进行评估。
答案 2 :(得分:0)
您在这里遇到的问题是 SpringJUnitRunner
在测试类中的任何方法之前在类级别运行。一种解决方案是将 spring 测试包装在一个父类中,并在该类中设置环境变量。
使用系统存根在 JUnit 5 中更容易实现 - https://github.com/webcompere/system-stubs
@ExtendWith(SystemStubsExtension.class)
public class SpringAppWithDynamicPropertiesTest {
private static WireMockServer wireMock = new WireMockServer(Options.DYNAMIC_PORT);
// sets the environment before Spring even starts
@SystemStub
private static EnvironmentVariables environmentVariables;
@BeforeAll
static void beforeAll() {
// we can manipulate the env vars here
environmentVariables.set("SERVER_URL", "something");
}
@Nested
@SpringBootTest(classes = {RestApi.class, App.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class InnerSpringTest {
@LocalServerPort
private int serverPort;
@Test
void someTest() {
// the spring app is testable with the given env
}
}
}
我认为在 JUnit 4 中也可以使用 Enclosed
运行器作为外部类并使用 EnvironmentVariablesRule
作为静态成员,并在外部类的 { 中设置环境变量{1}} 方法。