Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Value "Could not resolve placeholder" in Spring Boot Test

I want to take a Junit test for Spring-boot as below:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ApplicationTest.class})
public class TestOnSpring {
    @Value("${app.name}")
    private String appName;

    @Test
    public void testValue(){
        System.out.println(appName);
    }
}

and ApplicationTest.java like this

@ComponentScan("org.nerve.jiepu")
@EnableAutoConfiguration()
public class ApplicationTest {

    public static void main(String[] args) {
        SpringApplication.run(ApplicationTest.class, args);
    }
}

and my POM like this:

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.0.BUILD-SNAPSHOT</version>
    </parent>

When I run the test, I got below error information

Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'app.name' in string value "${app.name}"
    at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
    at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
    at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:204)
    at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:178)
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer$2.resolveStringValue(PropertySourcesPlaceholderConfigurer.java:172)
    at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:807)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1027)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:543)
    ... 31 more

But When I run this application as normal Java Application

@SpringBootApplication
public class Application {

    public static void main(String[] args){
        SpringApplication.run(Application.class, args);
    }
}

It work well!

What's wrong with it ? How should I take the junit test with Spring-boot? Thanks a lot!

like image 816
集成显卡 Avatar asked Oct 21 '15 10:10

集成显卡


3 Answers

You need to add

@PropertySource("classpath:application.properties")

to your class, so it will pick your normal configurations.

If you need different configurations for test you can add

@TestPropertySource(locations="classpath:test.properties")

If not just copy paste your config file to test/resources folder, then boot will pick from there.

See this.

like image 122
Maleen Abewardana Avatar answered Oct 28 '22 06:10

Maleen Abewardana


You can use the @SpringBootTest that will do create the PropertySourcesPlaceholderConfigurer automatically.

This is described in the Testing chapter of the Spring Boot documentation.

http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-configfileapplicationcontextinitializer-test-utility

like image 14
nucatus Avatar answered Oct 28 '22 07:10

nucatus


You have annotated your test class with @ContextConfiguration(classes = {ApplicationTest.class}). Wherein ApplicationTest.class does the component scan on a mentioned package. When you run your test it tries to find the configuration from the resources folder in 'main' instead of 'test'. If you annotate your class with @SpringBootTest(classes = {ClassToBeTested.class}) or just @SpringBootTest in this particular case, I think (not 100% sure) it will create a limited context and pick up the properties from test/resources.

If your properties are test specific, you can name your properties/yml file as application-test.properties or application-test.yml. And use @ActiveProfiles("test") in your test class so that it will always read test specific properties file.

I usually use this solution which works for me.

like image 7
horizon7 Avatar answered Oct 28 '22 07:10

horizon7