17

我有一个使用 Java 配置的 Spring(@Configuration等)的 Maven 项目。所引用的属性@Value存储在不同的位置,例如 Tomcat 的 context.xml。

为了进行测试,我创建了一个 .properties 文件来为组件和服务提供一些值。在我的 JUnit 测试(使用 spring 测试上下文)中,这个 .properties 文件是通过 .properties 文件添加的@PropertySource问题是不会从文件中加载这些值,而是将值标识符设置为值,例如(${someFlag:false}所以我得到了 String 以外的任何 ClassCastExceptions)。也不会设置默认值,所以我认为,这些值根本不会被处理。

我确信 Spring 会找到这个文件,因为当我更改它的值时,@PropertySource我会得到一些 FileNotFoundException。尽管如此,我已经尝试了不同的变体来指向这个文件,并且一切都有效(通过重命名产生 FileNotFoundException 进行测试):

  • 类路径:/test.properties(我的首选符号)
  • /test.properties
  • 文件:src/test/resources/test.properties

我也确信 Spring 本身可以工作,因为当我删除 时,被测类按预期@Value通过我的测试注入。@Autowired

在下面,您会发现问题场景被尽可能地精简。有关版本和依赖项,请参阅底部的 pom.xml。

我的服务.java

package my.package.service;

// Imports

@Service
public class MyService {

    @Value("${someFlag:false}")
    private Boolean someFlag;

    public boolean hasFlag() {
        return BooleanUtils.isTrue(someFlag);
    }
}

我的配置.java

@Configuration
@ComponentScan(basePackages = {"my.package.service"})
public class MyConfiguration {
}

MyServiceComponentTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {MyTestConfiguration.class})
public class MyServiceComponentTest {

    @Autowired
    private MyService service;

    @Test
    public void hasFlagReturnsTrue() {
        assertThat(service.hasFlag(), is(true));
    }
}

MyTestConfiguration.java

@Configuration
@Import({MyConfiguration.class})
@PropertySource("classpath:/test.properties")
public class MyTestConfiguration {
}

src/test/resources/test.properties

someFlag=true

pom.xml

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <spring.version>3.2.3.RELEASE</spring.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- Test dependencies -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.hamcrest</groupId>
        <artifactId>hamcrest-library</artifactId>
        <version>1.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
        <scope>test</scope>
    </dependency>
</dependencies>
4

3 回答 3

27

这里的问题是您还需要一个PropertySourcesPlaceholderConfigurer实际上负责解析${..}字段的方法,只需添加另一个创建此 bean 的 bean:

@Bean
public static PropertySourcesPlaceholderConfigurer propertiesResolver() {
    return new PropertySourcesPlaceholderConfigurer();
}
于 2013-07-11T18:24:55.483 回答
4

在 Spring 4 中,现在可以使用TestPropertySource

@TestPropertySource(value="classpath:/config/test.properties")

为了加载 junit 测试的特定属性

于 2015-04-01T11:53:05.440 回答
1

除了Biju Kunjummen 回答:

如果使用 @ConfigurationProperties 将属性注入 bean setter,则需要创建 ConfigurationPropertiesBindingPostProcessor(而不是 PropertySourcesPlaceholderConfigurer):

@Configuration
static class PropertyConfig {
    @Bean
    public static ConfigurationPropertiesBindingPostProcessor propertiesProcessor() {
        return new ConfigurationPropertiesBindingPostProcessor();
    }
}
于 2017-02-27T21:29:25.583 回答