Nee*_*ets 5 java mysql junit spring h2
我有一个在 MySQL 数据库上运行的服务。该服务是用 Java 编写的,并使用 Spring 和 JPA/Hibernate。我们使用 H2 数据库进行单元测试。问题是当我们运行测试时,在模式创建阶段我们会看到以下错误:
Index "USERNAME_INDEX" already exists; SQL statement: create index userName_index on MyTable1 (userName)
Run Code Online (Sandbox Code Playgroud)
问题似乎是我们的域类对于不同的表具有相同名称的索引:
MyTable : userName_index on column userName
MyTable1 : userName_index on column userName
Run Code Online (Sandbox Code Playgroud)
由于我们只看到MyTable1的错误,因此我们猜测MyTable的索引创建成功,然后MyTable1的索引创建失败。
显然,在 H2 中,索引名称在每个模式中必须是唯一的,但 MySQL 允许索引具有相同的名称,只要它们位于不同的表中即可。
我们无法更改索引名称。我还尝试将 MySQL 模式添加到连接 URL,如下所示:
"jdbc:h2:mem:./MyService;MODE=MySQL;DB_CLOSE_DELAY=-1;"
Run Code Online (Sandbox Code Playgroud)
如何使用当前索引名称使单元测试与 H2 一起工作?
小智 3
从版本 2.1.214 开始,H2 期望每个模式的索引名称是唯一的。我在文档中没有发现任何地方提到这一点。不过,我通过查看源代码确认了这一点。该类Schema使用 aConcurrentHashMap来包含与模式相关的所有索引,并且名称不以表名作为前缀,以使其在每个表中都是唯一的。
我通过创建表作为预测试操作的一部分(JUnit 测试中的 @Before 方法)来解决此限制。这并不理想,因为我有效地绕过了自动创建表的代码,但这对于我的情况来说已经足够了,因为我正在测试代码的不同部分。
正如 JB Nizet 提到的,使用 H2 这样的模拟数据库进行测试有一些局限性,并且它不能完美反映生产环境。每当我需要一个精确的类似生产环境时,我都会使用容器化数据库作为单元测试的一部分。
鉴于 H2 当前的局限性,希望这能为您提供如何处理特定场景的新视角。
| 归档时间: |
|
| 查看次数: |
1136 次 |
| 最近记录: |