java - 我应该将配置类注释为 @Configuration 以进行测试吗?

标签 java spring integration-testing spring-data spring-java-config

我花了一些时间解决 Spring Data 中缺少 org.joda.time.DateTime->java.util.Date 转换器的问题(当 Joda-Time 在类路径)。我找到了一个原因,但是它在 Spring 中产生了一个关于 @Configuration 注解的问题。

使用来自 spring-data-mongodb 的 AbstractMongoConfiguration 的标准应用程序配置:

@Configuration
@ComponentScan
@EnableMongoRepositories
public class AppConfig extends AbstractMongoConfiguration { ... }

显式使用 AppConfig 类的测试(使用 Spock,但使用了 spring-test 提供的内部机制):

@ContextConfiguration(classes = AppConfig)
class JodaDocRepositorySpec extends Specification {

    @Autowired
    private JodaDocRepository jodaDocRepository

    def "save document with DateTime"() {
        given:
            def jodaDoc = new JodaDoc(DateTime.now())
        when:
            def savedJodaDoc = jodaDocRepository.save(jodaDoc)
        then:
            savedJodaDoc.id
    }
}

它工作正常。但是当 AppConfig 中的@Configuration 注解被移除/注释时:

//@Configuration
@ComponentScan
@EnableMongoRepositories
public class AppConfig extends AbstractMongoConfiguration { ... }

测试失败:

org.springframework.core.convert.ConverterNotFoundException:
No converter found capable of converting from type org.joda.time.DateTime to type java.util.Date

据我所知,当它在上下文中显式注册时(通过 @ContextConfigurationregister 中的类),不需要为配置类使用 @Configuration () AnnotationConfigWebApplicationContext 中的方法)。无论如何都会处理这些类,并且会找到所有声明的 bean。当不同测试使用的测试上下文中的相同包中有 2 个相似的配置类时,不使用 @Configuration 来防止通过组件扫描进行检测有时很有用。

因此我认为这可能是 Spring 中的一个错误,它会根据使用情况或 @Configuration 注释在上下文中导致不同的内部 bean 处理。我比较了这两个案例的 Spring 日志,有一些差异,但我无法确定它们是由 Spring 内部类引起的。在提交错误之前,我想问:

我的问题。是否有一个可以解释的原因,为什么相同配置类的 Spring(在 @ContextConfiguration 中明确指出)使用(或不)Joda-Time 转换器取决于关于是否存在 @Configuration 注释?

我还创建了一个 quickstart project重现问题。 spring-data-mongodb 1.3.3,spring 4.0.0,joda-time 2.3。

最佳答案

在这种行为中一切正常。 AbstractMongoConfiguration@Configuration注解,但实际上这个注解不是@Inherited,所以你必须显式注解你的类。

当您删除 @Configuration 注释时,您的 AppConfig 类不是完整 配置。它作为一个 lite 配置处理只是因为它包含由 @Bean 注释的方法 - 请引用 org.springframework.context.annotation.ConfigurationClassUtils 中的方法>

  • isFullConfigurationCandidate()
  • isLiteConfigurationCandidate()
  • isFullConfigurationClass()

最后只有完整(由@Configuration 注释)配置类是进程并由配置后处理器增强 - 查看ConfigurationClassPostProcessor.enhanceConfigurationClasses()

关于java - 我应该将配置类注释为 @Configuration 以进行测试吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21034018/

相关文章:

java - 用于测试分布式系统的集成测试框架?

java - 双线性插值异常

java - 您是否在主类或适当的关系类中创建所有对象引用?

go - 在所有集成测试之前运行

java - jdbcTemplate.update 用于自动递增和唯一 ID 字段

java - spring 通用应用程序事件无法到达目的地

java - 容器内测试与用于集成测试的模拟对象

java - 重定向 URL 应为 : </> but was<null> in Junit

javascript - 如何生成预填充的可填写 PDF、更改其内容并解析内容

java - @RequestMapping 参数在路径中间