如何为自定义 Spring 引导样式启动库集成测试自动配置?

How to integration test auto configuration for a custom Spring Boot style starter library?

我正在编写一个库来提供一些在我使用的多个不同 Spring 启动应用程序之间共享的功能。

我想做一些类似于许多 Spring 引导启动程序库提供的自动配置。那个,或者其他一些简单的声明方式来将我的库与使用它的应用程序的 ApplicationContext 集成。

我找到了一些解释自动配置如何工作的资源。我可以解决上面的问题。

但是,我无法找到任何好的示例来说明如何将其作为我的库的测试套件的一部分进行测试,它是否适合与 Spring 启动应用程序集成。理想情况下,我会启动一个简单的 Spring 直接在库的测试中编写的引导应用程序,只是为了测试,向其添加正确的注释,然后能够断言正确的 beans 配置。

我已经尝试创建一个 TestApplication class 并使用 SpringBootTest 注释编写集成测试,但 TestApplication 在我的测试开始之前从未启动过。

为了测试我的图书馆,我该怎么做才能启动这样一个简单的应用程序?我的测试是用 Spock 和 Spock-Spring 编写的,以防与其他测试框架相比发生变化。

你的自动配置应该在你的主 spring application/test 启动时自动选择,所有 bean 都将在你的上下文中注册。它们将可用于自动接线并遵循您的条件和初始化顺序。

作为总结,请确保您有一个由 @Configuration class 注释的自动配置,其中 @Import 导入您的 @Configuration 注释配置 classes(在它们的内部,您使用 @Bean 注释的方法定义 bean)。还要确保你创建了一个 spring.factories 文件,其中包含你的 auto-configuration class 并且你删除了 spring boot maven 插件(为了包装正确)。

此外,请确保您的 auto-configuration 项目 没有 @SpringBootApplication@EnableAutoConfiguration@ComponentScan 或其他 spring 只需要在主 spring 引导项目中的引导注释(每个堆栈中应该有一个)。

另请参阅以下文章:


Spring 引导基于许多预制的自动配置父项目。您应该已经熟悉 spring 启动启动项目。

您可以通过执行以下简单步骤轻松创建自己的入门项目:

  1. 创建一些 @Configuration classes 来定义默认 bean。您应该尽可能多地使用外部属性以允许自定义,并尝试使用自动配置助手注释,如 @AutoConfigureBefore@AutoConfigureAfter@ConditionalOnBean@ConditionalOnMissingBean 等。您可以找到官方文档中每个注释的更详细信息Condition annotations

  2. 放置一个聚合所有 @Configuration classes 的自动配置 file/files。

  3. 创建一个名为 spring.factories 的文件并将其放在 src/main/resources/META-INF.

  4. spring.factories 中,将 org.springframework.boot.autoconfigure.EnableAutoConfiguration 属性 设置为 @Configuration classes 的逗号分隔值:

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=
    com.mycorp.libx.autoconfigure.LibXAutoConfiguration,
    com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration 使用此方法,您可以创建自己的自动配置 classes,spring-boot 将选择这些配置。 Spring-boot 自动扫描 spring.factories 文件的所有 maven/gradle 依赖项,如果找到一个,它会将其中指定的所有 @Configuration classes 添加到其自动-配置过程。

确保您的 auto-configuration 起始项目不包含 spring boot maven plugin,因为它会将项目打包为可执行 JAR,并且不会按预期由 class 路径加载 - spring 启动将无法找到您的 spring.factories 并且不会加载您的配置

我能够通过以下测试使其工作 class:

@SpringBootTest
@ContextConfiguration(classes = TestApplication)
class DummyIntegrationSpec extends Specification {

    @Autowired
    DummyService dummyService

    void 'dummy service should exist'() {
        expect:
        dummyService.getMessage() == DummyConfiguration.MESSAGE
    }
}

和此 TestApplication class 在 src/test/groovy/com/example/project/TestApplication.groovy

@SpringBootApplication(scanBasePackages = 'com.example.project.config')
@EnableAutoConfiguration
class TestApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(TestApplication)
    }

    static void main(String[] args) {
        SpringApplication.run(TestApplication, args)
    }
}

当我将 TestApplication class 从 src/main 移动到 src/test 时,为了启动 TestApplication 并加载正确的上下文,我必须进行的两个关键更改是:

  • 需要将 TestApplication class 添加到 ContextConfiguration 注释中

  • 我的库的 Java 配置文件所在的包需要添加到 SpringBootApplication scanBasePackages 字段

库自动配置确实遵循与 link tom 提供的结构类似的结构。