【发布时间】: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