如何在spring测试中设置环境变量或系统属性?

Han*_*örr 84 java spring environment-variables spring-test

我想编写一些检查已部署WAR的XML Spring配置的测试.不幸的是,某些bean需要设置一些环境变量或系统属性.在使用带有@ContextConfiguration的方便测试样式时,如何在初始化spring bean之前设置环境变量?

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:whereever/context.xml")
public class TestWarSpringContext { ... }
Run Code Online (Sandbox Code Playgroud)

如果我使用注释配置应用程序上下文,我没有看到一个钩子,我可以在初始化spring上下文之前执行某些操作.

Jim*_*aet 110

您可以在静态初始值设定项中初始化System属性:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:whereever/context.xml")
public class TestWarSpringContext {

    static {
        System.setProperty("myproperty", "foo");
    }

}
Run Code Online (Sandbox Code Playgroud)

静态初始化程序代码将在初始化spring应用程序上下文之前执行.

  • 傻我 - 好的,那会有用.甚至更好:可能是一个`@OutClass`方法设置系统属性和一个`@OpClass`方法来删除它也可以工作,并很好地清理自己.(但是没试过.) (11认同)
  • 尝试了 @BeforeClass - 在测试实例中设置其他属性之前,它可以很好地设置系统属性 (2认同)
  • 这样,系统属性就会在 Spring 应用程序上下文初始化之前初始化一次。当测试需要更改系统属性值时,方法会是什么样子?例如,测试 A 要求“myproperty”的值为“foo”,但测试 B 要求“myproperty”的值为“somethingelse”。 (2认同)

Ram*_*man 79

从Spring 4.1开始,正确的方法是使用@TestPropertySource注释.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:whereever/context.xml")
@TestPropertySource(properties = {"myproperty = foo"})
public class TestWarSpringContext {
    ...    
}
Run Code Online (Sandbox Code Playgroud)

请参阅Spring docsJavadocs中的@TestPropertySource .

  • 这提供了一个“环境”属性,它与“环境变量”不同。 (5认同)
  • 很好的答案,但遗憾的是没有为我工作,使用Spring 4.2.9,该属性总是空的.只有静态块工作...适用于应用程序属性,但不适用于系统属性. (4认同)
  • 该注释还支持属性文件路径。 (2认同)
  • 我可以在测试期间使用`@TestPropertySource(properties = {"spring.cloud.config.label = feature/branch"})切换Spring Cloud Config Client标签. (2认同)

Syl*_*are 10

对于 springboot,我认为这是最简单的方法,使用java@SpringBootTest中的注释:

@SpringBootTest(
    properties = { "spring.application.name=example", "ENV_VARIABLE=secret" }
)
public class ApplicationTest {

    // Write your tests here

}
Run Code Online (Sandbox Code Playgroud)

或者在kotlin中你可以这样做:

@SpringBootTest(
    properties = ["spring.application.name=example", "ENV_VARIABLE=secret"]
)
internal class ApplicationKTest {

    // Write your tests here

}
Run Code Online (Sandbox Code Playgroud)

这就是您的测试应该运行的,并使用您在注释中定义的属性覆盖属性。假设你的样子是application.yml这样的:

spring:
  application:
    name: "app"

db:
  username: "user"
  password: ${ENV_VARIABLE:default}
Run Code Online (Sandbox Code Playgroud)

那么在测试过程中它将是:

  • spring 属性spring.application.name将返回值"example"
  • 环境变量ENV_VARIABLE将返回"secret",因此如果您在代码中使用该值,db.password它将返回"secret"


anr*_*nre 7

也可以使用测试ApplicationContextInitializer来初始化系统属性:

public class TestApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>
{
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext)
    {
        System.setProperty("myproperty", "value");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在Spring上下文配置文件位置之外在测试类上配置它:

@ContextConfiguration(initializers = TestApplicationContextInitializer.class, locations = "classpath:whereever/context.xml", ...)
@RunWith(SpringJUnit4ClassRunner.class)
public class SomeTest
{
...
}
Run Code Online (Sandbox Code Playgroud)

这样,如果应为所有单元测试设置某个系统属性,则可以避免代码重复.


bla*_*dri 6

如果你希望你的变量对所有测试都有效,你可以application.properties在你的测试资源目录(默认情况下:)中有一个文件,src/test/resources它看起来像这样:

MYPROPERTY=foo
Run Code Online (Sandbox Code Playgroud)

这将被加载和使用,除非您通过@TestPropertySource或类似的方法定义- 加载属性的确切顺序可以在 Spring 文档第24外部化配置中找到


Har*_*apu 5

目前,这里所有的答案都只讨论系统属性,这些属性与设置更复杂的环境变量(特别是环境变量)不同。用于测试。值得庆幸的是,下面的类可以用于此,并且类文档中有很好的示例

EnvironmentVariables.html

来自文档的快速示例,已修改为与@SpringBootTest一起使用

@SpringBootTest
public class EnvironmentVariablesTest {
   @ClassRule
   public final EnvironmentVariables environmentVariables = new EnvironmentVariables().set("name", "value");

   @Test
   public void test() {
     assertEquals("value", System.getenv("name"));
   }
 }
Run Code Online (Sandbox Code Playgroud)

  • EnvironmentVariables 规则是第三方库的一部分,使用 hacky 反射来更改 JVM 内存中环境的缓存值,甚至不更改实际的环境变量。所以,我不想使用它或推荐任何人这样做。 (6认同)

归档时间:

查看次数:

116207 次

最近记录:

6 年,4 月 前