I've got a Maven project which uses Java-configured Spring (@Configuration
etc.). Properties which are referenced by @Value
are stored in different places, e.g. Tomcat's context.xml.
For testing I've created a .properties file to provide some values for the components and services. In my JUnit test (which uses a spring test context) this .properties file is added via @PropertySource
. The problem is that the values will not be loaded from the file, instead the value identifier is set as value, e.g. ${someFlag:false}
(so I get ClassCastExceptions for any other than String). Also the default value will not be set, so I think, the values won't be processed at all.
I'm sure Spring finds this file because when I change the value of @PropertySource
I get some FileNotFoundException. Nevertheless I've tried different variants to point to this file an all have worked (tested by renaming which produced FileNotFoundException):
I'm also sure that Spring itself works, because when I remove the @Value
, the class under test is injected via @Autowired
in my test as expected.
Down below you'll find the problem scenario stripped down as much as possible. For versions and dependencies please see the pom.xml at the bottom.
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>
The issue here is you need a PropertySourcesPlaceholderConfigurer
also which is actually responsible for resolving the ${..}
fields, just add another bean which creates this bean:
@Bean
public static PropertySourcesPlaceholderConfigurer propertiesResolver() {
return new PropertySourcesPlaceholderConfigurer();
}
With Spring 4, it's now possible to use TestPropertySource:
@TestPropertySource(value="classpath:/config/test.properties")
In order to load specific properties for a junit test
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With