Java 用H2数据库对DAO层进行单元测试

Java 用H2数据库对DAO层进行单元测试,java,postgresql,unit-testing,h2,dao,Java,Postgresql,Unit Testing,H2,Dao,在互联网上读了很多书之后,我发现使用内存中的数据库(如H2)对DAO层进行单元测试似乎是一种很好的做法。背后的想法是避免使用生产数据库 很好,所以我设置了一个H2 DB并激活了H2 PostgreSQL兼容模式,因为我的生产DB在Postgres上。我现在面临的问题是:当我在H2上运行原始SQL查询以构建测试数据库时,H2不接受此查询为有效查询: 改变MYERP.ecriture\u comptable\u id所拥有的MYERP.ecriture\u comptable.id的序列; 我想使

在互联网上读了很多书之后,我发现使用内存中的数据库(如H2)对DAO层进行单元测试似乎是一种很好的做法。背后的想法是避免使用生产数据库

很好,所以我设置了一个H2 DB并激活了H2 PostgreSQL兼容模式,因为我的生产DB在Postgres上。我现在面临的问题是:当我在H2上运行原始SQL查询以构建测试数据库时,H2不接受此查询为有效查询:

改变MYERP.ecriture\u comptable\u id所拥有的MYERP.ecriture\u comptable.id的序列;
我想使用PostgreSQL兼容模式并不能保证H2会接受所有Postgres特定的语法。对于其他数据库,如MySQL,可能也会发生这种情况

那么在这种情况下使用h2数据库有什么意义呢?
我遗漏了什么吗?

单元测试应该把重点放在单元测试上。PostgreSQL是应用程序外部的,因此并不属于任何使用它的DAO的一部分:不应该编写使用任何此类外部数据库的“单元测试”

使用数据库进行集成测试可能没问题,但正如您已经注意到的,当您使用不同的数据库执行集成测试时,可能会出现多个问题(我知道很少有应用程序只使用ANSI-SQL,没有任何触发器或其他特定于供应商的SQL扩展,如PostgreSQLs中的
UPSERT
,或您文章中的SQL)


那么,如果您的生产基地也在内存中呢?这相当困难,我认为集成测试可以,但不要称之为单元测试。所有这些都突出了在数据库中执行业务逻辑的痛点(例如,通过您现在无法测试的触发器)或者使用特定于供应商的sql,这种sql有几个优点,但在更改基础数据库供应商时却不能很好地发挥作用。

“*那么在这种情况下使用h2数据库有什么意义?”-没有。我从不理解为什么人们认为这些是有效的测试。我个人认为,使用不同的DBMS进行测试和生产不是“好做法”。我实际上认为它是无用的。我的目的是测试DAO层的所有CRUD方法是否都能正常工作。我们认为它实际上更像是一个集成测试,而不是单元测试。无论如何,我现在认为直接测试Postgre DB会更有意义。如果我不介意的话,我不会改变数据库的状态DB(使用回滚)这应该没问题。您认为呢?您可以让测试在Docker容器或其他容器中启动新的PostgreSQL实例,创建表,进行测试并将其拆下。使用共享数据库(例如测试实例的数据库)是有风险的,因为在执行集成测试时,它无法使用或关闭以进行维护。但是,这样的测试没有什么错,只要它是一个集成测试。这种东西总是令人讨厌的,当你没有Docker(或类似的东西)时更是如此事实上,我在Docker上收到了一个演示数据库。所以我想我应该利用它!很高兴听到这个消息,祝你一切顺利!如果你需要更多帮助,请随时回来谢谢你的帮助!