我有一个应用程序 “单元” 测试在执行过程中使用与Oracle数据库的真实连接。

可以想象,这些测试需要太多时间才能执行,因为它们需要初始化某些春季上下文并与Oracle实例进行通信。除此之外,我们必须管理复杂的机制,例如交易,以避免在执行测试后的数据库修改(即使我们使用Spring类似的有用类 AbstractAnnotationAwareTransactionalTests).

因此,我的想法是通过内存数据库逐步替换此Oracle测试实例。我会用 hsqldb 也许更好 h2.

我的问题是知道最好的方法是什么。我的主要关注点是与内存数据库结构的构建和参考数据的插入有关。

当然,我可以使用一些工具从Oracle提取数据库结构 SQL Developer 或者 TOAD, ,然后修改这些脚本以使其适应 hsqldb 或者 h2 语。但是我认为这不是更好的方法。


实际上,我已经在另一个项目上使用 hsqldb, ,但是我已经手动编写了所有脚本来创建表。幸运的是,我只有很少的桌子可以创建。在此步骤中,我的主要问题是“翻译”用于将表创建表中的Oracle脚本 hsqldb 语。

例如,使用以下SQL命令在Oracle中创建的表:

CREATE TABLE FOOBAR (
    SOME_ID NUMBER,
    SOME_DATE DATE, -- Add primary key constraint
    SOME_STATUS NUMBER,
    SOME_FLAG NUMBER(1) DEFAULT 0 NOT NULL);

需要“翻译” hsqldb 至:

CREATE TABLE FOOBAR (
    SOME_ID NUMERIC,
    SOME_DATE TIMESTAMP PRIMARY KEY,
    SOME_STATUS NUMERIC,
    SOME_FLAG INTEGER DEFAULT 0 NOT NULL);

在我当前的项目中,有太多的桌子可以手动做...


所以我的问题:

  • 您可以为我提供什么建议?
  • h2 或者 hsqldb 提供一些工具来从Oracle连接生成其脚本?

技术信息

Java 1.6,春季2.5,Oracle 10.G,Maven 2


编辑

有关我的单位测试的一些信息:

在我使用的应用程序中 hsqldb, ,我进行了以下测试: - 一些“基本”单元测试,与DB无关。 - 对于DAO测试,我使用了 hsqldb 执行数据库操作,例如CRUD。 - 然后,在服务层上,我使用了 Mockito 嘲笑我的DAO对象,以专注于服务测试,而不是整个应用程序(即服务 + DAO + DB)。

在我当前的应用程序中,我们的情况最坏:DAO层测试需要运行Oracle连接。服务层确实 不是 使用(尚未)任何模拟对象模拟DAO。因此服务测试 需要Oracle连接。

我知道模拟和内存数据库是两个分隔点,我将尽快解决。但是,我的第一步是 尝试 要通过内存数据库删除Oracle连接,然后我将使用我的 Mockito 知识以增强测试。

请注意,我还想将单元测试与集成测试分开。后者将需要对Oracle数据库进行访问,以执行“真实”测试,但是我的主要关注点(这是这个问题的目的)是,今天几乎所有我的单位测试都不孤立地进行。

有帮助吗?

解决方案

使用内存 / Java数据库进行测试。这将确保测试与现实世界更接近现实世界,而不是尝试“抽象”测试中的数据库。这样的测试可能也更容易编写和维护。另一方面,您可能想在测试中“抽象”的是UI,因为UI测试通常很难自动化。

您发布的Oracle语法与H2数据库(我刚刚对其进行了测试)效果很好,因此H2似乎比HSQLDB更好地支持Oracle语法。免责声明:我是H2的作者之一。如果某件事不起作用,请将其发布在H2邮件列表中。

无论如何,您应该在版本控制系统中具有数据库的DDL语句。您也可以使用这些脚本进行测试。可能您还需要支持多个模式版本 - 在这种情况下,您可以编写版本更新脚本(Alter Table ...)。使用Java数据库,您也可以测试这些数据库。

顺便说一句,使用H2或HSQLDB时,您不一定需要使用内存模式。即使您坚持数据,两个数据库也很快。而且它们易于安装(只是一个JAR文件),并且比Oracle所需的内存要少得多。

其他提示

最新的HSQLDB 2.0.1通过语法兼容性标志,SQL.Syntax_ora = true支持双重,Rownum,NextVal和Currval的Oracle语法。以相同的方式,将字符串与空字符串的串联和在唯一约束中的null限制与其他标志一起处理。大多数Oracle功能(例如to_char,to_date,nvl等)已经内置。

目前,要使用简单的Oracle类型(例如号码),您可以使用类型定义:

将类型编号创建为数字

设置标志时,下一个快照将允许数字(n)和其他方面兼容。

http://hsqldb.org/support/

更新:] 10月4日发布的快照将大多数特定于Oracle类型转换为ANSI SQL类型。 HSQLDB 2.0还支持与Oracle相同的ANSI SQL间隔类型和日期 /时间戳算术。

您的单位测试是做什么的?如果他们测试了DDLS和存储过程的适当工作,则应将测试“更近”地写入Oracle:没有Java代码,或者没有Spring和其他NICE Web接口,完全集中在DB上。

如果要测试Java和Spring中实现的应用程序逻辑,则可以使用模拟对象/数据库连接将测试独立于数据库。

如果您想整体测试工作(反对模块化开发和测试原理),则可以虚拟化数据库并在该实例上进行测试,而不会冒着进行一些令人讨厌的不可逆修改的风险。

只要您的测试自身清理(您似乎已经知道如何设置),则针对真实数据库实例运行测试就没有错。实际上,这是我通常更喜欢的方法,因为您将测试尽可能接近生产的东西。

不兼容似乎很小,但最终不久后就咬了一口。在一个很好的情况下,您可能会摆脱一些讨厌的SQL翻译 /广泛的嘲弄。在不良情况下,该系统的某些部分将无法测试,我认为这是关键业务系统的不可接受的风险。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top