使用profile进行Spring集成测试

Dav*_*d V 20 java spring spring-mvc spring-test

在我们的Spring Web应用程序中,我们使用Spring bean配置文件来区分三种场景:开发,集成和生产.我们使用它们连接到不同的数据库或设置其他常量.

使用Spring bean配置文件非常适合更改Web应用程序环境.

我们遇到的问题是我们的集成测试代码需要改变环境.在这些情况下,集成测试会加载Web应用程序的应用程序上下文.这样我们就不必重新定义数据库连接,常量等(应用DRY原则).

我们设置了如下的集成测试.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = ["classpath:applicationContext.xml"])
public class MyTestIT
{
   @Autowired
   @Qualifier("myRemoteURL")  // a value from the web-app's applicationContext.xml
   private String remoteURL;
   ...
 }
Run Code Online (Sandbox Code Playgroud)

我可以使用它在本地运行@ActiveProfiles,但这是硬编码的,导致我们的测试在构建服务器上失败.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = ["classpath:applicationContext.xml"])
@ActiveProfiles("development")
public class MyTestIT
{ ... }
Run Code Online (Sandbox Code Playgroud)

我也试过使用@WebAppConfiguration希望它可能以某种方式spring.profiles.active从Maven 导入属性,但这不起作用.

另外需要注意的是,我们还需要配置代码,以便开发人员可以运行Web应用程序,然后使用IntelliJ的测试运行器(或其他IDE)运行测试.这对于调试集成测试来说要容易得多.

Sam*_*nen 36

正如其他人已经指出的那样,您可以选择使用Maven来设置spring.profiles.active系统属性,确保使用@ActiveProfiles,但这对于在IDE中运行的测试来说并不方便.

有关设置活动配置文件的编程方法,您有几个选项.

  1. Spring 3.1:编写一个自定义ContextLoader,通过在上下文中设置活动配置文件来准备上下文Environment.
  2. Spring 3.2:自定义ContextLoader仍然是一个选项,但更好的选择是ApplicationContextInitializer通过initializers属性实现和配置它@ContextConfiguration.您的自定义初始化程序可以Environment通过编程方式设置活动配置文件.
  3. Spring 4.0:上述选项仍然存在; 但是,从Spring Framework 4.0开始,有一个专门ActiveProfilesResolver用于此目的的新专用API:以编程方式确定要在测试中使用的活动配置文件集.一个ActiveProfilesResolver可以通过注册resolver的属性@ActiveProfiles.

问候,

Sam(Spring TestContext Framework的作者)

  • 是的,在[测试章节]中有一个如何使用自定义`ActiveProfilesResolver`的示例(http://docs.spring.io/spring/docs/current/spring-framework-reference/html/testing.html# Spring框架参考手册的testcontext-ctx-management-env-profiles-ActiveProfilesResolver)。 (2认同)

Jim*_*Cox 15

我遇到了类似的问题:我希望使用默认配置文件运行所有集成测试,但允许用户使用代表不同环境甚至db风格的配置文件覆盖,而无需更改@ActiveProfiles值.如果您使用Spring 4.1+和自定义ActiveProfilesResolver,这是可行的.

此示例解析程序查找系统属性spring.profiles.active,如果它不存在,它将委托给只使用@ActiveProfiles批注的默认解析程序.

public class SystemPropertyActiveProfileResolver implements ActiveProfilesResolver {

private final DefaultActiveProfilesResolver defaultActiveProfilesResolver = new DefaultActiveProfilesResolver();

@Override
public String[] resolve(Class<?> testClass) {

    if(System.getProperties().containsKey("spring.profiles.active")) {

        final String profiles = System.getProperty("spring.profiles.active");
        return profiles.split("\\s*,\\s*");

    } else {

        return defaultActiveProfilesResolver.resolve(testClass);
    }
}
Run Code Online (Sandbox Code Playgroud)

}

在你的测试类中,你会像这样使用它:

@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles( profiles={"h2","xyz"},
resolver=SystemPropertyActiveProfileResolver.class)
public class MyTest { }
Run Code Online (Sandbox Code Playgroud)

除了检查是否存在系统属性以设置活动配置文件之外,您当然可以使用其他方法.希望这有助于某人.


Eld*_*ael 5

如果您想避免对配置文件进行硬编码,您可能需要使用系统属性 spring.profiles.active并将其设置为您在特定环境中所需的任何内容,例如,我们为不同的环境提供"dev","stage"和"prod"配置文件; 我们还有一个"测试","测试本地"和"测试服务器"配置文件供我们测试.

请记住,通过使用逗号分隔值列表(例如"test,test-qa"),您可以在该系统属性中拥有多个配置文件.

您可以在maven surefire插件中的maven项目中指定系统属性,或者像这样传递它们:

mvn -DargLine="-DpropertyName=propertyValue"
Run Code Online (Sandbox Code Playgroud)