【问题标题】:How to perform unit tests with h2 database where bpchar is used?如何使用使用 bpchar 的 h2 数据库执行单元测试?
【发布时间】:2019-10-19 09:43:41
【问题描述】:

我有一个使用 postgres 数据库的 spring + hibernate 应用程序。我需要为控制器编写单元测试。对于测试,我想使用 h2 数据库,但不幸的是在 create-drop 期间测试崩溃,给我留下了 bpchar 数据类型无效的信息。我想知道如何解决这个问题,以便我可以运行测试。

我无法将使用 bpchar 的列更改为 varchar,它需要保持原样。我也尝试设置 postgresql 模式,但没有帮助。 我唯一的解决方案是使用嵌入式 postgres 数据库来执行测试,或者我可以使用其他任何方法吗?

【问题讨论】:

    标签: java spring postgresql testing h2


    【解决方案1】:

    我唯一的解决方案是使用嵌入式 postgres 数据库来执行测试,或者我可以使用其他任何方法吗?

    您尝试将 postgres 特定的数据类型与 h2 (没有它)一起使用。当然,它不起作用。

    如果您无法更改此字段的类型 - 在测试中使用嵌入式 postgres。

    【讨论】:

      【解决方案2】:

      实际上你可以在你的 application.properties 中这样做让 H2 知道:

      spring.datasource.url=jdbc:h2:mem:testdb;INIT=CREATE TYPE BPCHAR AS CHARACTER NOT NULL
      

      还要确保为您的测试关闭数据库的自动配置。您可以通过添加:

      @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
      public class MyTestForTableWithBpcharColumn {
      

      【讨论】:

        【解决方案3】:

        解决这个问题的一个有趣的方法是Test Containers

        由于 Postgres 没有嵌入式模式,但您可以使用上述框架在测试之前启动 docker 容器,如果您使用 Flyway 或 Liquibase 之类的东西或集成您的自定义解决方案,则可以创建架构并应用迁移.

        这个想法是容器将在运行时准备好并可供测试使用。 测试通过后(无论实际结果如何,成功或失败)都可以停止容器。

        启动容器可能非常昂贵(几秒钟),但是您可以在测试期间利用弹簧缓存配置,因此当模块中的第一个测试开始时,容器实际上已启动,但是,它在测试和测试用例之间重复使用,因为应用程序上下文不会重新启动。

        由于您在测试用例上放置了 Spring 的 @Transactional 注释,因此在测试之间保持数据库清洁也成为一项微不足道的任务,因此 Spring 在每次测试后人为地回滚事务。由于在 Postgres 中,即使是 DDL 命令也可以是事务性的,它应该已经足够好了。

        这种方法的唯一限制是,如果您计划在本地运行这些测试,您应该在构建机器或本地开发机器上使用 docker(在 Linux 和 Mac OS 上这不是问题,但在 Windows至少需要有 Windows 10 专业版才能安装 docker 环境)。

        我在实际项目中使用过这种方法,发现它对集成测试非常有效。

        【讨论】:

          猜你喜欢
          • 2019-04-01
          • 2019-11-15
          • 1970-01-01
          • 2021-10-24
          • 2017-12-30
          • 2018-09-12
          • 2015-11-20
          • 1970-01-01
          • 2013-07-13
          相关资源
          最近更新 更多