【问题标题】:sharing properties between spring and non-spring tests在弹簧和非弹簧测试之间共享属性
【发布时间】:2016-08-26 07:47:29
【问题描述】:

我的大多数数据库测试不使用 Spring,因为这样它们启动速度更快。但我还想运行实际运行整个 Spring Boot 应用程序的冒烟测试。

我想将数据库连接参数放在一个地方。要做到这一点,我认为我有两个选择:

  1. 在我的非 Spring 测试中模拟/重用 Spring 的属性加载
  2. 将我在运行时计算的属性(不能使用常量注释)注入到烟雾测试中的 Spring 配置中

知道如何实现这些吗?或者也许有一些更简单的方法?

【问题讨论】:

    标签: java spring spring-boot integration-testing spring-test


    【解决方案1】:

    您可以将数据库连接参数导出为与application.properties 中的属性完全一致的系统属性。由于 Spring Boot 处理外部化配置的方式,这些值将覆盖 Spring 配置中的属性(或 YAML,无论您使用哪个)文件中的值,然后您只需要在非 Spring 测试中使用系统属性即可。

    虽然我也建议将这些 DB 测试作为 Spring 套件的一部分 - 实际上只有在执行单个测试时才能提高速度;除非您有 @DirtiesContext 测试或使用不同 @ActiveProfiles 注释的测试,否则 Spring 将缓存应用程序上下文,并且每个测试套件只初始化一次。

    这是来自the official documentation的引述:

    Spring TestContext 框架提供一致的 Spring ApplicationContexts 和 WebApplicationContexts 加载以及这些上下文的缓存。 支持缓存加载的上下文很重要,因为启动时间可能会成为问题 — 不是因为 Spring 本身的开销,而是因为 Spring 容器实例化的对象需要时间来实例化。 例如,具有 50 到 100 个 Hibernate 映射文件的项目可能需要 10 到 20 秒来加载映射文件,并且在每个测试夹具中运行每个测试之前产生该成本会导致整体测试运行速度变慢,从而降低开发人员的工作效率。

    默认情况下,一旦加载,配置的 ApplicationContext 会被重复用于每个测试。因此,每个测试套件只产生一次设置成本,并且后续测试执行速度要快得多。 在这种情况下,术语测试套件意味着所有测试都在同一个 JVM 中运行 — 例如,所有测试都从 Ant 运行、Maven 或 Gradle 为给定项目或模块构建。

    【讨论】:

    • 系统属性很难看,但我承认,它们可以完成工作。在接受您的回答之前,我会等待一些“侵入性较小”的解决方案。将测试迁移到 spring 不是一种选择:每次 ~200ms vs 5s。这对 TDD 来说有很大的不同
    • 同意,但我没有看到更简单的出路。我本人一直更喜欢the approach of adding an environment prepared application listener,但这对于您的用例来说有点重量级。在您的情况下,您必须在某处有一个静态 Map 字段来保存您将传递给侦听器的配置,所以我认为系统属性仍然是一种侵入性较小的方式
    【解决方案2】:

    您可以将数据库连接属性存储在专用的 Java db.properties 文件中,您可以为标准测试和 Spring Boot 测试加载该文件。

    然后,您可以通过指定自定义 spring.config.location 来指示 Spring Boot 除了加载标准 Spring Boot 应用程序属性文件之外还加载 db.properties

    Spring Boot 参考手册的Application property files 部分提供了您应该需要的所有详细信息。

    【讨论】:

      猜你喜欢
      • 2011-10-23
      • 2022-07-21
      • 2015-12-29
      • 2011-11-27
      • 2018-08-31
      • 1970-01-01
      • 1970-01-01
      • 2017-12-22
      相关资源
      最近更新 更多