62

我有一个 Web 应用程序,其中存在一个典型问题,即它需要针对不同环境使用不同的配置文件。一些配置作为 JNDI 数据源放置在应用程序服务器中,但是一些配置保留在属性文件中。

因此,我想使用 Spring 配置文件功能。

我的问题是我没有让测试用例运行。

上下文.xml:

<context:property-placeholder 
  location="classpath:META-INF/spring/config_${spring.profiles.active}.properties"/>

测试:

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({
    TestPreperationExecutionListener.class
    })
@Transactional
@ActiveProfiles(profiles = "localtest")
@ContextConfiguration(locations = {
    "classpath:context.xml" })
public class TestContext {

  @Test
  public void testContext(){

  }
}

问题似乎是加载配置文件的变量没有解决:

Caused by: java.io.FileNotFoundException: class path resource [META-INF/spring/config_${spring.profiles.active}.properties] cannot be opened because it does not exist
at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:157)
at org.springframework.core.io.support.PropertiesLoaderSupport.loadProperties(PropertiesLoaderSupport.java:181)
at org.springframework.core.io.support.PropertiesLoaderSupport.mergeProperties(PropertiesLoaderSupport.java:161)
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.postProcessBeanFactory(PropertySourcesPlaceholderConfigurer.java:138)
... 31 more

当前配置文件应使用@ActiveProfile注释进行设置。由于这是一个测试用例,我将无法使用web.xml. 如果可能的话,我也想避免运行时选项。测试应该按原样运行(如果可能)。

如何正确激活配置文件?是否可以使用 context.xml 设置配置文件?我可以在实际调用正常上下文的 test-context.xml 中声明变量吗?

4

5 回答 5

64

我可以推荐这样做吗,像这样定义你的测试:

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({
    TestPreperationExecutionListener.class
    })
@Transactional
@ActiveProfiles(profiles = "localtest")
@ContextConfiguration
public class TestContext {

  @Test
  public void testContext(){

  }

  @Configuration
  @PropertySource("classpath:/myprops.properties")
  @ImportResource({"classpath:context.xml" })
  public static class MyContextConfiguration{

  }
}

在 myprops.properties 文件中包含以下内容:

spring.profiles.active=localtest

有了这个你的第二个属性文件应该得到解决:

META-INF/spring/config_${spring.profiles.active}.properties
于 2012-11-13T16:24:43.823 回答
7

看着 Biju 的回答,我找到了一个可行的解决方案。

我创建了一个额外的上下文文件test-context.xml

<context:property-placeholder location="classpath:config/spring-test.properties"/>

包含简介:

spring.profiles.active=localtest

并加载测试:

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({
    TestPreperationExecutionListener.class
    })
@Transactional
@ActiveProfiles(profiles = "localtest")
@ContextConfiguration(locations = {
    "classpath:config/test-context.xml" })
public class TestContext {

  @Test
  public void testContext(){

  }
}

这在创建多个测试用例时节省了一些工作。

于 2012-11-13T16:39:45.167 回答
1

这里最好的方法是删除 @ActiveProfiles 注释并执行以下操作:

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({
    TestPreperationExecutionListener.class
    })
@Transactional
@ContextConfiguration(locations = {
    "classpath:config/test-context.xml" })
public class TestContext {

  @BeforeClass
  public static void setSystemProperty() {
        Properties properties = System.getProperties();
        properties.setProperty("spring.profiles.active", "localtest");
  }

  @AfterClass
  public static void unsetSystemProperty() {
        System.clearProperty("spring.profiles.active");
  }

  @Test
  public void testContext(){

  }
}

你的 test-context.xml 应该有以下内容:

<context:property-placeholder 
  location="classpath:META-INF/spring/config_${spring.profiles.active}.properties"/>
于 2015-06-02T07:27:24.510 回答
1
public class LoginTest extends BaseTest {
    @Test
    public void exampleTest( ){ 
        // Test
    }
}

从基础测试类继承(此示例是testng而不是jUnit,但ActiveProfiles是相同的):

@ContextConfiguration(locations = { "classpath:spring-test-config.xml" })
@ActiveProfiles(resolver = MyActiveProfileResolver.class)
public class BaseTest extends AbstractTestNGSpringContextTests { }

MyActiveProfileResolver可以包含确定使用哪个配置文件所需的任何逻辑:

public class MyActiveProfileResolver implements ActiveProfilesResolver {
    @Override
    public String[] resolve(Class<?> aClass) {
        // This can contain any custom logic to determine which profiles to use
        return new String[] { "exampleProfile" };
    }
}

这将设置配置文件,然后用于解决测试所需的依赖关系。

于 2018-04-27T10:15:43.440 回答
0

@EnableConfigurationProperties 需要在那里(你也可以注释你的测试类),来自 test/resources 的 application-localtest.yml 将被加载。jUnit5 示例

@ExtendWith(SpringExtension.class)
@EnableConfigurationProperties
@ContextConfiguration(classes = {YourClasses}, initializers = ConfigFileApplicationContextInitializer.class)
@ActiveProfiles(profiles = "localtest")
class TestActiveProfile {

    @Test
    void testActiveProfile(){

    }
}
于 2020-07-09T04:28:24.743 回答