Spring boot tests - Can't find test properties

Viewed 29359

I have a spring boot project and it works great. I now want to write tests for my application and I am running into some configuration headaches.

Spring boot created a test class for me called ApplicationTests. It's real simple and it looks like this:

@RunWith(SpringRunner.class)
@SpringBootTest
public class DuurzaamApplicationTests {
    @Test
    public void contextLoads() {
    }    
}

Now when I start the tests I get this error:

java.lang.IllegalArgumentException: Could not resolve placeholder 'company.upload' in value "${company.upload}"

I have a properties.yml file in the src/test/resources directory and for some reason it isn't loaded. I have tried all different kind of annotations from examples on the Internet and yet none of them work.

How can I tell spring boot tests to use an application.yml file to load the properties from?

7 Answers

To my surprise, when you load properties files in Spring Boot Test, .yml is not supported. It's noted in the documentation, although implicitly.

From the link above:

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/test/context/TestPropertySource.html

Supported File Formats

Both traditional and XML-based properties file formats are supported — for example, "classpath:/com/example/test.properties" or "file:/path/to/file.xml".

.yml is not mentioned.

And, after changing my .yml to .properties and rewrite the values in xx.xx.xx=value form, the key-values pairs can be read correctly.

So strange.

EDIT:

Now I find a ticket address this issue; seems a long-known bug in Spring.

https://github.com/spring-projects/spring-framework/issues/18486

@PropertySource and @TestPropertySource do not work with YAML. See this.

I also tested it myself. Try creating 2 files - *.yml and *.properties and see it for yourself.

To make *.yml work most people use @SpringBootTest, but if it's not what you want and you would like to use @ContextConfiguration instead, you are in for a bit of surprise.

For me the above solutions did not work and any environment variables were still overriding the test properties defined in @TestPropertySource even though https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html indicates that this source should have higher precedence than environment variables. The only solution that worked for me was to manually define a PropertyPlaceholderConfigurer bean in a test configuration class and set it with highest precedence.

This was with Spring Boot 1.5.15.RELEASE

@Configuration
@TestPropertySource(properties = "/application-test.properties")
@Slf4j
public class IntegrationTestConfiguration {

@Bean
public static PropertyPlaceholderConfigurer properties() {
    PropertyPlaceholderConfigurer ppc
          = new PropertyPlaceholderConfigurer();
    Resource[] resources = new ClassPathResource[]
          { new ClassPathResource( "/application-test.properties" ) };
    ppc.setLocations( resources );
    ppc.setIgnoreUnresolvablePlaceholders( true );
    ppc.setOrder( Ordered.HIGHEST_PRECEDENCE );

    return ppc;
}

/// ....

@RunWith( SpringRunner.class )
@ActiveProfiles( "test" )
@Import( IntegrationTestConfiguration.class )
@SpringBootTest( webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT )
public class MyTest {

I had the same error message, my problem was a application.properties in src\test\resources which was missing the new properties

Sometimes your application-test.properties file can't be found because it is in a subfolder off the class path.

for example this may not be found, because the file is actually not directly in the class path.

@TestPropertySource("classpath:application-test.properties")

but this will be found if the file is in the config folder off of a path in the class path

@TestPropertySource("classpath:config/application-test.properties")

We can use annotation of @ActiveProfiles("test") that support application-test.yml or application-test.properties

Related