H2 postgresql模式似乎不适合我

Ume*_*cha 19 java postgresql jdbc h2

您好我的应用程序访问Postgres数据库,我有许多预定义的查询(排名,分区,复杂的连接等)我对Postgres.现在我想用小测试数据对这些查询行为进行单元测试.所以我从H2/Junit开始.我发现大多数Postgres查询比如Rank,Partition,Complex case等更新等等.所以我想到使用H2 PosgreSQL兼容模式,认为所有的postgres查询都适用于H2,如果我错了请纠正我.

我按照H2文档说使用PostgreSQL模式,使用数据库URL jdbc:h2:〜/ test; MODE = PostgreSQL或SQL语句SET MODE PostgreSQL.

我启用模式使用SET MODE PostgreSQL,我试图触发一个涉及rank()的查询并在postgres中工作,但它不起作用H2.它给了我以下例外

Function "RANK' not found; in SQL statement
Run Code Online (Sandbox Code Playgroud)

请指导我是H2和数据库测试的新手.提前致谢.我正在使用H2 jdbc驱动程序来解决postgres查询,认为H2 Posgress兼容模式将允许我触发postgres查询.

Cra*_*ger 35

因此我想到使用H2 PosgreSQL兼容模式,认为所有postgres查询都适用于H2,如果我错了请纠正我

我担心这不是真的.

H2尝试模拟PostgreSQL语法并支持一些功能和扩展.它永远不会完全匹配PostgreSQL的行为,并且不支持所有功能.

您拥有的唯一选择是:

  • 在测试中使用PostgreSQL; 要么
  • 停止使用H2不支持的功能

我建议用Pg进行测试.编写测试工具是相对简单的,initdb是一个postgres实例并启动它进行测试然后将其撕下来.

根据评论更新:

"单元"和"集成"测试之间没有强硬路线.在这种情况下,H2也是外部组件.Purist单元测试将作为测试工具的一部分对查询进行虚拟响应.对H2进行测试与对PostgreSQL进行测试同样是一种"集成"测试.事实上,它处于进程内和内存中是一种便利,但在功能上并不重要.

如果你想进行单元测试,你应该为你的应用编写另一个数据库目标,与你的"PostgreSQL","SybaseIQ"等目标一起使用.称之为"MockDatabase".这应该只返回查询的预期结果.它并不真正运行查询,它只存在于测试其余代码的行为.

就个人而言,我认为这是浪费时间,但这就是单元测试纯粹主义者为避免将外部依赖性引入测试工具所做的事情.

如果您坚持对数据库组件进行单元(而不是集成)测试但不能/不会编写模拟接口,则必须找到使用现有模块的方法.H2将是一个合理的候选者 - 但你必须编写一个新的后端,其中包含一组适用于H2的新查询,你不能只重用你的PostgreSQL后端.正如我们已经建立的那样,H2不支持您使用PostgreSQL所需的所有功能,因此您必须找到使用H2执行相同操作的不同方法.一种选择是创建一个简单的H2数据库,其中包含"预期"结果和返回这些结果的简单查询,完全忽略了实际应用程序的模式.这里唯一真正的缺点是维持它可能是一个巨大的痛苦......但这是单元测试.

就个人而言,我只是用PostgreSQL进行测试.除非我正在测试单独的类或模块作为窄接口明确定义的单元,否则我不在乎是否有人将其称为"单元"或"集成"测试.我会对数据验证类进行单元测试.对于数据库接口代码,纯粹单元测试没什么意义,我只是做集成测试.

虽然有一个进程内存数据库很方便,但它不是必需的.您可以编写测试工具,以便设置代码成为initdb新的PostgreSQL并启动它; 然后拆卸代码杀死postmaster并删除datadir.我在这个答案中写了更多关于这一点.

也可以看看:

至于:

如果所有具有预期结束数据集的查询在Postgress中正常工作,我可以假设它在所有其他dbs中都能正常工作

如果我理解你正确的说法是肯定的,那就是这种情况 - 如果你的其余代码使用PostgreSQL中的数据集,它通常应该与包含来自另一个数据库的相同数据的数据集相同.当然,只要它使用简单的数据类型而不是数据库特定的功能.

  • "人们说"?参考/链接?对我来说听起来像BS.对于一件事,"单元"和"集成"测试之间没有强硬路线.另一方面,H2也是外部组件.Purist单元测试将作为测试工具的一部分对查询进行虚拟响应. (4认同)