【问题标题】:@TestPropertySource doesn't work for JUnit test with AnnotationConfigContextLoader in Spring 1.2.6@TestPropertySource 不适用于 Spring 1.2.6 中使用 AnnotationConfigContextLoader 的 JUnit 测试
【发布时间】:2015-12-14 12:26:02
【问题描述】:

似乎我在 Spring 4.1.17 中使用 Spring Boot 1.2.6.RELEASE 所做的任何事情都不起作用。我只想访问应用程序属性并在必要时用测试覆盖它们(不使用黑客手动注入 PropertySource)

这不起作用..

@TestPropertySource(properties = {"elastic.index=test_index"})

这个也不行..

@TestPropertySource(locations = "/classpath:document.properties")

也不是这个..

@PropertySource("classpath:/document.properties")

完整的测试用例..

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
@TestPropertySource(properties = {"elastic.index=test_index"})
public class PropertyTests {
    @Value("${elastic.index}")
    String index;

    @Configuration
    @TestPropertySource(properties = {"elastic.index=test_index"})
    static class ContextConfiguration {
    }

    @Test
    public void wtf() {
        assertEquals("test_index", index);
    }
}

导致

org.junit.ComparisonFailure: 
Expected :test_index
Actual   :${elastic.index}

3.x 和 4.x 之间似乎有很多相互矛盾的信息,我找不到任何可以确定的东西。

任何见解将不胜感激。干杯!

【问题讨论】:

标签: java spring junit spring-boot


【解决方案1】:

您尝试过使用@PropertySource("classpath:document.properties")@PropertySource("classpath*:document.properties") 吗?

【讨论】:

  • 都试过了。他们在 4.x 中引入了@TestPropertySource,虽然看起来有问题。
  • 是的。我记得我在集成测试期间遇到了同样的问题。如果他们还没有,我希望他们能尽快修复它。
  • @ThomasBeauvais 你有问题ID的参考吗?我想跟踪他们是否解决了它
【解决方案2】:

您对@Value 的使用需要PropertySourcesPlaceholderConfigurer bean 来解析${...} 占位符。在此处查看接受的答案:@Value not set via Java-configured test context

【讨论】:

  • 对,问题是为什么?这似乎是一个巨大的疏忽。为什么这个功能消失了?无论如何..如果这是唯一的方法..那就这样吧..虽然@TestPropertySource应该可以工作..
  • @Don Bottstein:能否请您突出显示 PropertySourcesPlaceholderConfigurer 的 Sources 部分,因为我想很多像我这样的人在他们已经有可用的 PropertyPlaceholderConfigurer 时忽略了该部分,这还不够。跨度>
【解决方案3】:

事实证明,最好的方法(直到 Spring 修复这个疏忽)是一个 PropertySourcesPlaceholderConfigurer,它将引入 test.properties(或任何你想要的)和 @Import 或扩展 @Configuration

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import java.io.IOException;

@Configuration
public class PropertyTestConfiguration {
    @Bean
    public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() throws IOException {
        final PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
        ppc.setLocations(ArrayUtils.addAll(
                        new PathMatchingResourcePatternResolver().getResources("classpath*:application.properties"),
                        new PathMatchingResourcePatternResolver().getResources("classpath*:test.properties")
                )
        );

        return ppc;
    }

}

这允许您在 application.properties 中定义默认值并在 test.properties 中覆盖它们。当然,如果你有多个方案,那么你可以根据需要配置PropertyTestConfiguration类。

并在单元测试中使用它。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public class PropertyTests {
    @Value("${elastic.index}")
    String index;

    @Configuration
    @Import({PropertyTestConfiguration.class})
    static class ContextConfiguration {
    }
}

【讨论】:

  • 您真正需要的只是应用程序上下文中的PropertySourcesPlaceholderConfigurer,然后@PropertySource 就可以工作了。
  • 您可以在 @Configuration 类中执行此操作(格式在此处不起作用): public @Bean PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); }
【解决方案4】:

我使用@TestPropertySourcelocations 属性覆盖(或添加)属性。

这对我有用(春季 4.2.4):

@TestPropertySource(locations = {
   "classpath:test.properties",
   "classpath:test-override.properties" })

但是像下面这样的覆盖属性没有:

@TestPropertySource(
  locations = {"classpath:test.properties"},
  properties = { "key=value" })

尽管 javadoc 说这些属性具有最高优先级。可能是一个错误?

更新

该错误应该在 Spring boot 1.4.0 及更高版本中修复。请参阅commit which closes the issue。 至此,以上述方式声明的属性应该优先。

【解决方案5】:

对我来说 @TestPropertySource("classpath:xxxxxxxx.properties") 有效

【讨论】:

    【解决方案6】:

    我遇到了@TestPropertySource 的问题。未找到 test.properties

    下面是修复之前的那个

    @RunWith(SpringRunner.class)
    @ContextConfiguration(classes = ExtContext.class)
    @TestPropertySource(locations = "classpath: test.properties")
    

    我删除了 classpath: 和 test.properties 之间的空格,如下所示

    @RunWith(SpringRunner.class)
    @ContextConfiguration(classes = ExtContext.class)
    @TestPropertySource(locations = "classpath:test.properties")
    

    这对我有用,当在 classpth 中找不到 test.properties 时。也适合你

    【讨论】:

      【解决方案7】:

      如果您遇到此问题并且尝试将 yaml 作为属性文件,请记住 spring @TestPropertySource@PropertySource 不适用于 yaml 文件,并且无法正确加载属性。

      https://github.com/spring-projects/spring-boot/issues/10772#issuecomment-339581902

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-09
        • 1970-01-01
        • 2011-07-28
        • 2012-05-24
        • 2019-10-20
        • 2021-11-02
        • 1970-01-01
        相关资源
        最近更新 更多