【问题标题】:Integration testing native SQL query when using Hibernate使用 Hibernate 时集成测试本机 SQL 查询
【发布时间】:2013-07-12 13:39:17
【问题描述】:

我使用 Hibernate 和广泛采用的 Hibernate 查询语言在我的 DAO 中定义查询。

无论如何,与原生 SQL 查询相比,HQL 有时无法执行特定任务。

例如,以下 Postgres 表达式不能“转换”为 HQL:

my_date > current_date - interval '10 year'

这意味着在某些情况下我正在编写本机查询。考虑到我正在使用另一个数据库进行集成测试 (http://hsqldb.org/),它不反映上面 Postgres 表达式的语法。这会在使用此类原生查询的 DAO 方法期间导致测试异常。

您如何处理此类情况?我只能想到以下场景:

  • 永远不要使用本机查询并尝试在 HQL 中构建所有内容(可能吗?)
  • 不要测试使用此类查询的方法(不高兴)
  • 生产和开发使用相同的数据库(性能问题)

其他更有趣的解决方案?谢谢

【问题讨论】:

  • 您正在使用另一个数据库进行单元测试?我认为您误解了单元测试的目的。您根本不应该访问数据库。当您开始访问数据库时,您现在正在使用集成测试。单元测试旨在涵盖一个特定的 unit 代码(通常是一个类),并且应该模拟该类可能具有的任何和所有外部依赖项。
  • @ColinMorelli 那么如何在单元测试中测试 DAO?您如何模拟数据库?
  • 也许一种解决方案是扩展一些 hibernate/jpa 类(例如 EntityManager)以在将 SQL 发送到 HSQLDB 之前对其进行更改。
  • @Wizche 我认为你没有抓住重点。如果您将单元测试和集成测试分开,那么您的问题就会得到解答。您的单元测试不与您的数据库对话。您的集成测试应该绝对与您的生产环境的副本对话。因此,您只需与开发 PostgreSQL 数据库交谈。那么你的问题就完全避免了。使用不同系统针对不同环境进行测试在某种程度上违背了测试的目的。您应该始终以模仿生产为目标。
  • @Wizche 不,您应该使用生产 schema 的精确副本(不包含数据)。您的集成测试应该插入任何需要插入的测试数据,然后进行 DAO 调用以确保返回正确的数据。无论哪种情况,您都应该查询 Postgres,因为这就是您在生产中所拥有的

标签: java hibernate unit-testing orm integration-testing


【解决方案1】:

通常,集成测试的目的是针对(非常)与生产环境相似的环境进行测试,因此 IMO 您应该使用相同的数据库引擎。但是对于单元测试,使用 HSQLDB 很好。在这种情况下不幸的是,依赖于 Postgres 的类无法进行单元测试,您必须等到集成测试才能检测到错误。

顺便说一句,您提到的 Postgres SQL 的结果可以通过在 Java 上执行日期算术来实现。

Calendar currentDateCal = Calendar.getInstance();
currentDateCal.add(Calendar.YEAR, -10);
Date currentDate = currentDateCal.getTime(); // bind this currentDate object into your HQL parameter

【讨论】:

  • 您根本不应该在单元测试中与数据库对话,它应该在没有外部依赖的情况下测试代码的特定部分
  • 感谢 gerry,虽然很多人完全反对使用不同的数据库进行“任何”测试,但我认为你是对的,如果我依赖于数据库语法,我可以使用相同的数据库或调整查询。
猜你喜欢
  • 2017-04-14
  • 2011-04-25
  • 1970-01-01
  • 1970-01-01
  • 2012-01-11
  • 1970-01-01
  • 2011-06-03
  • 2019-05-06
  • 1970-01-01
相关资源
最近更新 更多