@Value未通过Java配置的测试上下文设置

Mar*_*zer 14 java testing junit spring properties

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

For testing I've created a .properties file to provide some values for the components and services. In my JUnit test (which uses a spring test context) this .properties file is added via @PropertySource. The problem is that the values will not be loaded from the file, instead the value identifier is set as value, e.g. ${someFlag:false} (so I get ClassCastExceptions for any other than String). Also the default value will not be set, so I think, the values won't be processed at all.

I'm sure Spring finds this file because when I change the value of @PropertySource I get some FileNotFoundException. Nevertheless I've tried different variants to point to this file an all have worked (tested by renaming which produced FileNotFoundException):

  • classpath:/test.properties (my preferred notation)
  • /test.properties
  • 文件:源/测试/资源/ test.properties

我也确信Spring本身可以工作,因为当我删除它时@Value,被测试的类会按照@Autowired预期在我的测试中注入.

在下面你会发现问题场景尽可能地被剥离.有关版本和依赖项,请参阅底部的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

MyConfiguration.java

@Configuration
@ComponentScan(basePackages = {"my.package.service"})
public class MyConfiguration {
}
Run Code Online (Sandbox Code Playgroud)

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));
    }
}
Run Code Online (Sandbox Code Playgroud)

MyTestConfiguration.java

@Configuration
@Import({MyConfiguration.class})
@PropertySource("classpath:/test.properties")
public class MyTestConfiguration {
}
Run Code Online (Sandbox Code Playgroud)

SRC /测试/资源/ test.properties

someFlag=true
Run Code Online (Sandbox Code Playgroud)

的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>
Run Code Online (Sandbox Code Playgroud)

Bij*_*men 20

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

@Bean
public static PropertySourcesPlaceholderConfigurer propertiesResolver() {
    return new PropertySourcesPlaceholderConfigurer();
}
Run Code Online (Sandbox Code Playgroud)

  • 如果Spring在调用`propertiesResolver()`之后生成一些bean,它可能在某些情况下有效,但否则会失败.为了确保它有效,你需要使它"静止". (3认同)