我有一个使用Java配置的Spring(@Configuration
等)的Maven项目。由@Value
引用的属性存储在不同的位置,例如Tomcat的context.xml。
为了测试,我创建了一个.properties文件来为组件和服务提供一些值。在我的JUnit测试(使用弹簧测试上下文)中,此.properties文件通过@PropertySource
添加。 问题是不会从文件加载值,而是将值标识符设置为值,例如${someFlag:false}
(所以除了String之外我得到了ClassCastExceptions)。此外,默认值将不会被设置,因此我认为,根本不会处理这些值。
我确信Spring找到了这个文件,因为当我更改@PropertySource
的值时,我得到了一些FileNotFoundException。尽管如此,我已经尝试了不同的变体来指向这个文件已经工作(通过重命名测试产生的FileNotFoundException):
我也确信Spring本身有效,因为当我删除@Value
时,测试中的类会按照预期在我的测试中通过@Autowired
注入。
在下方,您会发现问题场景尽可能地被剥离。有关版本和依赖项,请参阅底部的pom.xml。
package my.package.service;
// Imports
@Service
public class MyService {
@Value("${someFlag:false}")
private Boolean someFlag;
public boolean hasFlag() {
return BooleanUtils.isTrue(someFlag);
}
}
@Configuration
@ComponentScan(basePackages = {"my.package.service"})
public class MyConfiguration {
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {MyTestConfiguration.class})
public class MyServiceComponentTest {
@Autowired
private MyService service;
@Test
public void hasFlagReturnsTrue() {
assertThat(service.hasFlag(), is(true));
}
}
@Configuration
@Import({MyConfiguration.class})
@PropertySource("classpath:/test.properties")
public class MyTestConfiguration {
}
someFlag=true
<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>
答案 0 :(得分:20)
这里的问题是你需要一个PropertyPlaceholderConfigurer
,它实际上负责解析${..}
字段,只需添加另一个创建这个bean的bean:
@Bean
public static PropertySourcesPlaceholderConfigurer propertiesResolver() {
return new PropertySourcesPlaceholderConfigurer();
}
答案 1 :(得分:4)
使用Spring 4,现在可以使用TestPropertySource:
@TestPropertySource(value="classpath:/config/test.properties")
为了加载junit测试的特定属性
答案 2 :(得分:1)
除了Biju Kunjummen回答:
如果使用@ConfigurationProperties将属性注入bean设置器,则需要创建ConfigurationPropertiesBindingPostProcessor(而不是PropertySourcesPlaceholderConfigurer):
@Configuration
static class PropertyConfig {
@Bean
public static ConfigurationPropertiesBindingPostProcessor propertiesProcessor() {
return new ConfigurationPropertiesBindingPostProcessor();
}
}