Spring boot 如何使用Spring框架为Junit测试设置环境变量

Spring boot 如何使用Spring框架为Junit测试设置环境变量,spring-boot,junit4,Spring Boot,Junit4,我有一个类,它只返回带有System.getEnv的环境变量,我正试图为它编写一个JUnit测试,但总是得到null。 我试图使用应用程序test.yml设置所有变量,并尝试了许多注释,如 @RunWith(SpringJUnit4ClassRunner.class) @TestPropertySource(locations="classpath:/application-test.yml") 还有许多其他的,但仍然没有成功。有人知道如何简单地做到这一点吗?Spring与环境变量无关。它可以

我有一个类,它只返回带有
System.getEnv
的环境变量,我正试图为它编写一个JUnit测试,但总是得到null。 我试图使用
应用程序test.yml
设置所有变量,并尝试了许多注释,如

@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(locations="classpath:/application-test.yml")

还有许多其他的,但仍然没有成功。有人知道如何简单地做到这一点吗?

Spring与环境变量无关。它可以读取它们,但据我所知,它不会说任何内容,这与系统属性不同

环境变量意味着存在于环境中

因此,您有以下选项:

选项1

使用允许模拟静态方法调用的powermock。这个库不是spring的一部分,所以您可以在测试范围内使用它,这样它就不会对生产产生影响(powermock jar将不在生产依赖项列表中)

选项2

使用一些外部类包装静态调用,然后使用常规模拟框架对其进行模拟/或者加载同一接口的不同bean,因为您仍然在使用Spring测试。代码将如下所示:

  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代码中设置环境是非常棘手的,因为环境变量不应该以编程方式更改


您可以阅读可能的解决方法,并在程序中对其进行评估。

有多种方法

选项1

如果您正在IDE(eclipse或IntelliJ IDEA)中运行测试,则可以在IDE中为测试设置变量。如果您使用的是maven,则可以通过Surefire插件设置系统属性-


更多细节可以在这里找到-

这里的问题是
SpringJUnitRunner
在测试类中的任何方法之前在类级别运行。一种解决方案是将spring测试封装在父类中,并在该类中设置环境变量

在JUnit5中,使用系统存根更容易实现这一点-

这里有一个spring示例():

@ExtendWith(SystemStubsExtension.class)
公共类SpringAppWithDynamicProperties测试{
私有静态WireMockServer wireMock=新的WireMockServer(Options.DYNAMIC_PORT);
//在Spring开始之前设置环境
@系统存根
私有静态环境变量环境变量;
@以前
静态void beforeAll(){
//我们可以在这里操纵环境变量
environmentVariables.set(“服务器URL”、“某物”);
}
@嵌套
@SpringBootTest(类={RestApi.class,App.class},
webEnvironment=SpringBootTest.webEnvironment.RANDOM\u端口)
类内测试{
@本地服务器端口
专用int服务器端口;
@试验
无效测试(){
//spring应用程序可以使用给定的环境进行测试
}
}
}

我认为在JUnit4中也可以实现同样的效果,它为外部类提供了一个
封闭的
运行程序,并使用
环境变量规则
作为静态成员,在外部类的
@BeforeClass
方法中设置环境变量。

为什么不使用PowerMock模拟系统类?或者,您可以尝试一些类似于我不认为PowerMock是Spring框架的一部分的东西,对吗?不幸的是,对于策略,我只能使用官方的spring类。我在链接的线程中尝试了解决方案,但仍然得到空值。您正在进行什么类型的测试?是单元还是集成?
<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>
"classpath:config_#{systemProperties['env']}/db.properties"