java - @Value 不是通过 Java 配置的测试上下文设置的

标签 java spring testing properties junit

我有一个使用 Java 配置的 Spring(@Configuration 等)的 Maven 项目。 @Value 引用的属性存储在不同的位置,例如Tomcat 的 context.xml。

为了测试,我创建了一个 .properties 文件来为组件和服务提供一些值。在我的 JUnit 测试(使用 spring 测试上下文)中,这个 .properties 文件是通过 @PropertySource 添加的。 问题是不会从文件中加载值,而是将值标识符设置为值,例如${someFlag:false} (所以我得到了 String 以外的任何 ClassCastExceptions)。也不会设置默认值,所以我认为这些值根本不会被处理。

我确信 Spring 会找到这个文件,因为当我更改 @PropertySource 的值时,我得到了一些 FileNotFoundException。尽管如此,我已经尝试了不同的变体来指向这个文件,并且所有的工作都有效(通过重命名产生 FileNotFoundException 进行测试):

  • classpath:/test.properties(我的首选表示法)
  • /test.properties
  • 文件:src/test/resources/test.properties

我也确信 Spring 本身可以工作,因为当我删除 @Value 时,测试中的类会按预期通过 @Autowired 在我的测试中注入(inject)。

在下面,您会发现问题场景已被尽可能地精简。版本和依赖请看底部的 pom.xml。

MyService.java

package my.package.service;

// Imports

@Service
public class MyService {

    @Value("${someFlag:false}")
    private Boolean someFlag;

    public boolean hasFlag() {
        return BooleanUtils.isTrue(someFlag);
    }
}

MyConfiguration.java

@Configuration
@ComponentScan(basePackages = {"my.package.service"})
public class MyConfiguration {
}

MyServiceComponentTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {MyTestConfiguration.class})
public class MyServiceComponentTest {

    @Autowired
    private MyService service;

    @Test
    public void hasFlagReturnsTrue() {
        assertThat(service.hasFlag(), is(true));
    }
}

MyTestConfiguration.java

@Configuration
@Import({MyConfiguration.class})
@PropertySource("classpath:/test.properties")
public class MyTestConfiguration {
}

src/test/resources/test.properties

someFlag=true

pom.xml

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

最佳答案

这里的问题是你需要一个 PropertySourcesPlaceholderConfigurer 也实际上负责解析 ${..} 字段,只需添加另一个创建这个 bean 的 bean:

@Bean
public static PropertySourcesPlaceholderConfigurer propertiesResolver() {
    return new PropertySourcesPlaceholderConfigurer();
}

关于java - @Value 不是通过 Java 配置的测试上下文设置的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17600605/

相关文章:

java - 上下文初始化期间出现异常 -

java - 有哪些可能的 AOP 用例?

testing - 线程 Maven 使用顺序单元测试构建?

c# - 使用 NUnit 在不同的应用程序域中运行单元测试

java - Spring & Wildfly 异步请求

java - 在 tomcat 中创建反向代理的最简单方法是什么?

java - Spring MVC 的 REST API 部署

java - Spring boot中如何配置拦截器?

http - testng - 登录后的 HTTP REST 测试

java - Spring Boot 应用程序和 MessageSource