我想使用H2的PostgreSQL兼容模式,认为所有的PostgreSQL查询都可以在H2上运行,请纠正我如果我错了。
恐怕这不是真的。H2试图模拟PostgreSQL语法并支持一些功能和扩展,但它永远不会完全匹配PostgreSQL的行为,并且不支持所有功能。
你唯一的选择是:
- 在测试中使用PostgreSQL;或者
- 停止使用H2不支持的功能。
我建议在测试中使用Pg。编写一个测试工具来初始化postgres实例并启动测试,然后在测试结束后关闭它相对简单。
根据评论更新:
“单元测试”和“集成测试”之间没有硬性界限。在这种情况下,H2也是一个外部组件。纯粹的单元测试将作为测试工具的一部分使用虚拟响应器进行查询。针对H2的测试与针对PostgreSQL的测试一样是“集成”测试。它在进程内和内存中的事实是方便,但并不具有功能上的重要性。
如果你想进行单元测试,你应该为你的应用程序编写另一个数据库目标,与你的“PostgreSQL”、“SybaseIQ”等目标并列。比如说,称之为“MockDatabase”。它只返回查询的预期结果,而不是实际运行查询,仅存在于测试代码的行为。个人认为这是巨大的时间浪费,但这是单元测试纯粹主义者为避免引入外部依赖项到测试工具中所做的事情。
如果你坚持要对你的DB组件进行单元(而不是集成)测试,但不能/不愿编写模拟接口,那么你必须找到一种使用现有接口的方法。H2将是一个合理的候选人 - 但你必须编写一个新的后端,具有适用于H2的新查询集,你不能只重用你的PostgreSQL后端。正如我们已经确定的,H2不支持你需要在PostgreSQL中使用的所有功能,因此你必须找到使用H2完成相同任务的不同方法。其中一种选择是创建一个简单的H2数据库,其中包含“预期”的结果和简单的查询,返回这些结果,完全忽略真实应用程序的模式。唯一的真正缺点是维护可能会非常麻烦...但这就是单元测试。
个人而言,我只会使用PostgreSQL进行测试。除非我正在测试作为狭窄界面和定义明确的单元的单个类或模块,否则我不关心是否将其称为“单元”或“集成”测试。我会对数据验证类进行单元测试。对于数据库接口代码纯粹主义者来说,单元测试几乎没有意义,我只会做集成测试。
虽然在进程内存数据库中进行测试很方便,但并非必需。您可以编写测试工具包,以使设置代码initdb创建新的PostgreSQL并启动它;然后拆卸代码杀死postmaster并删除datadir。我在
this answer中详细介绍了这个问题。
另请参见:
-
Running PostgreSQL in memory only
至于:
如果所有查询与预期的结束数据集在Postgress中正常工作,我可以假设它在所有其他数据库中也能正常工作。
如果我正确理解你的意思,那么是的 - 如果你的代码其余部分使用来自PostgreSQL的数据集工作,则通常使用包含相同数据的来自另一个数据库的数据集将产生相同的结果。当然,只要使用简单数据类型而不是特定于数据库的功能。