Java @Value 在 Spring Boot 测试中“无法解析占位符”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33256702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 14:31:12  来源:igfitidea点击:

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

javaspringjunitspring-boot

提问by u1559249

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

我想对 Spring-boot 进行 Junit 测试,如下所示:

@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

和 ApplicationTest.java 像这样

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

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

and my POM like this:

和我的 POM 是这样的:

<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.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

但是当我像普通 Java 应用程序一样运行这个应用程序时

@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!

它出什么问题了 ?我应该如何使用 Spring-boot 进行 junit 测试?非常感谢!

采纳答案by Maleen Abewardana

You need to add

你需要添加

@PropertySource("classpath:application.properties")

@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")

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

If not just copy paste your config file totest/resourcesfolder, then boot will pick from there.

如果不只是将您的配置文件复制粘贴到test/resources文件夹,则启动将从那里选择。

See this.

看到这个

回答by nucatus

You can use the @SpringBootTestthat will do create the PropertySourcesPlaceholderConfigurerautomatically.

您可以使用@SpringBootTestPropertySourcesPlaceholderConfigurer自动创建的。

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

这在 Spring Boot 文档的测试章节中有描述。

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

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

回答by horizon7

You have annotated your test class with @ContextConfiguration(classes = {ApplicationTest.class}). Wherein ApplicationTest.classdoes 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 @SpringBootTestin this particular case, I think (not 100% sure) it will create a limited context and pick up the properties from test/resources.

您已使用@ContextConfiguration(classes = {ApplicationTest.class}). 其中ApplicationTest.class组件扫描提到的包。当您运行测试时,它会尝试从“main”而不是“test”的资源文件夹中查找配置。如果您使用@SpringBootTest(classes = {ClassToBeTested.class})或仅@SpringBootTest在这种特殊情况下注释您的类,我认为(不是 100% 确定)它将创建一个有限的上下文并从测试/资源中获取属性。

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

如果您的属性是特定于测试的,您可以将您的属性/yml 文件命名为application-test.propertiesapplication-test.yml。并@ActiveProfiles("test")在您的测试类中使用,以便它始终读取测试特定的属性文件。

I usually use this solution which works for me.

我通常使用这个对我有用的解决方案。