Spring Boot Configuration – Properties not loaded

I had recently a very interesting problem using Spring Boot and the automagic concerning the configuration.

The Problem

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'demo.MyApplicationTests': Injection of autowired dependencies failed; 
	nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.String demo.MyApplicationTests.url; 
	nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'my.url' in string value "${my.url}" at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
		~[spring-beans-4.1.7.RELEASE.jar:4.1.7.RELEASE] 
	Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'my.url' in string value "${my.url}" at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174) 
		~[spring-core-4.1.7.RELEASE.jar:4.1.7.RELEASE]

Configuration was not available in my Unit tests but it was working fine in the normal application. I spend a lot of time searching but without real good post concerning this issue.

This code already wasn’t working:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MyWebappApplication.class)
@WebAppConfiguration
public class MyApplicationTests {
    @Value("${my.url}")
    String url;

    @Test
    public void test() {
        System.out.println(url);
    }
}

Even if my application.yml / application.properties was looking good:

my:
   url: any kind of String we inject

The solution

Now here the working sample, do you see the difference?

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyWebappApplication.class)
@WebAppConfiguration
public class MyApplicationTests {
    @Value("${my.url}")
    String url;

    @Test
    public void test() {
        System.out.println(url);
    }
}

Yes it is just the @SpringApplicationConfiguration instead of the @ContextConfiguration annotation. (Even if the first is itself just a meta-annotation of the second.) If you look into this new annotation you will find that it uses a different loader class, which makes the difference.

@ContextConfiguration(loader = SpringApplicationContextLoader.class)
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface SpringApplicationConfiguration

That’s the trick. Having it in place the Spring Application configuration is successfully parsed an available in your unit test. Doesn’t matter if YAML or just property file.

Paul Sterl has written 54 articles

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>