我的应用程序访问Postgres数据库,我有许多预定义的查询(等级、分区、复杂连接等)我对Postgres开火。现在我想用小的测试数据对这些查询行为进行单元测试。
所以我从H2/JUnit开始。我发现大多数Postgres查询,如等级查询、分区查询、更新时的复杂情况等,所以我考虑使用H2 PosgreSQL兼容性模式--所有Postgres查询都能在H2上工作吗?
我跟踪了H2文档,说:
要使用PostgreSQL模式,请使用数据库URL :h2:~/test;mode = PostgreSQL或SQL语句集模式PostgreSQL。
我使用SET MODE PostgreSQL
启用了模式,并尝试触发一个涉及rank()
的查询,并在Postgres中工作,但它没有运行H2。它给了我以下例外:
Function "RANK' not found; in SQL statement
我是H2和数据库测试的新手。我使用H2 JDBC驱动程序来触发Postgres查询,因为我认为H2控件兼容模式将允许我触发Postgres查询。
发布于 2014-06-15 15:03:43
所以我想使用H2 PosgreSQL兼容性模式,因为我认为所有的postgres查询都会在H2上工作,如果我错了,请纠正我
恐怕那不是真的。
H2试图模仿PostgreSQL语法,并支持一些特性和扩展。它永远不会完全匹配PostgreSQL的行为,也不支持所有特性。
您唯一的选择是:
我建议使用Pg进行测试。编写一个测试工具(initdb是postgres实例)并启动它以进行测试是相对简单的,然后再将其撕掉。
根据评论更新:
在“单元”和“集成”测试之间没有硬线。在这种情况下,H2也是一个外部组件。纯粹的单元测试将有一个虚拟的查询响应器作为测试工具的一部分。对H2的测试与对PostgreSQL的测试一样,也是一种“集成”测试。事实上,它是在进程中和内存中是一个方便,但功能上没有意义.
如果您想要进行单元测试,您应该为您的应用程序编写另一个数据库目标,以便与您的"PostgreSQL“、"SybaseIQ”等目标一起使用。叫它,说,"MockDatabase“。这应该只是返回查询的预期结果。它并不真正运行查询,它只存在于测试其余代码的行为。
就我个人而言,我认为这是对时间的巨大浪费,但这正是单元测试纯粹主义者为避免在测试工具中引入外部依赖而做的事情。
如果您坚持让单元(而不是集成)测试您的DB组件,但是不能/不会编写模拟接口,那么您必须找到一种使用现有接口的方法。H2是这方面的合理人选--但是您必须编写一个新的后端,其中包含一组适用于H2的新查询,您不能仅仅重用您的PostgreSQL后端。正如我们已经建立的那样,H2不支持您需要在PostgreSQL中使用的所有特性,因此您必须找到不同的方法来使用H2来完成相同的任务。一种选择是创建一个包含“预期”结果的简单H2数据库和返回这些结果的简单查询,完全忽略实际应用程序的模式。这里唯一真正的缺点是它可能是一个很大的痛苦维持..。但那是单元测试。
就我个人而言,我只想用PostgreSQL进行测试。除非我是在测试单个类或模块,这些类或模块作为狭义接口、定义良好的单元独立存在,否则我不在乎有人称它为“单元”还是“集成”测试。我将对数据验证类进行单元测试。对于数据库接口,代码纯粹的单元测试没有什么意义,我只做集成测试。
虽然有一个进程内的内存数据库是方便的,但它不是必需的。您可以编写您的测试工具,以便安装代码initdb
是一个新的PostgreSQL并启动它;然后,该解压缩代码将杀死postmaster并删除datadir。我在this answer上写了更多关于这个的文章。
另请参阅:
至于:
如果所有带有预期结束数据集的查询都能正常工作,那么我可以假设它在所有其他dbs中都能正常工作。
如果我正确地理解了您所说的话,那么是的--如果您的其余代码与来自PostgreSQL的数据集一起工作,它通常应该对包含来自另一个数据库的相同数据的数据集同样工作。当然,只要它使用的是简单的数据类型,而不是特定于数据库的特性。
https://stackoverflow.com/questions/24223631
复制相似问题