从 Oracle 实例创建内存中数据库结构

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

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

因此,我的想法是逐步用内存中数据库替换此 Oracle 测试实例。我将使用hsqldb或更好的h2

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

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


事实上,我已经在另一个项目上使用 ,但我已经手动编写了所有脚本来创建表。幸运的是,我只有几个表要创建。在此步骤中,我的主要问题是将用于创建表的Oracle脚本“翻译”到该语言中。hsqldbhsqldb

例如,使用以下 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);

在我当前的项目中,有太多的表需要手动完成...


所以我的问题:

  • 为了实现这一目标,您可以给我什么建议?
  • 是否或提供了一些工具来从 Oracle 连接生成脚本?h2hsqldb

技术资料

Java 1.6, Spring 2.5, Oracle 10.g, Maven 2


编辑

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

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

在我当前的应用程序中,我们遇到了最坏的情况:DAO 层测试需要一个 Oracle 连接才能运行。服务层(尚未)使用任何模拟对象来模拟 DAO。因此,服务测试也需要 Oracle 连接。

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

请注意,我还希望将单元测试与集成测试分开。后者需要访问Oracle数据库才能执行“真实”测试,但我的主要担忧(这就是这个问题的目的)是,今天几乎所有的单元测试都不是孤立运行的。


答案 1

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

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

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

顺便说一句,在使用H2或HSQLDB时,您不一定需要使用内存模式。即使您保留数据,这两个数据库的速度也很快。而且它们易于安装(只是一个jar文件),并且比Oracle需要更少的内存。


答案 2

最新的 HSQLDB 2.0.1 通过语法兼容性标志(sql.syntax_ora=true)支持 DUAL、ROWNUM、NEXTVAL 和 CURRVAL 的 ORACLE 语法。以同样的方式,字符串与 NULL 字符串的串联以及 UNIQUE 约束中对 NULL 的限制也使用其他标志进行处理。大多数ORACLE功能,如TO_CHAR,TO_DATE,NVL等已经内置。

目前,要使用简单的ORACLE类型(如NUMBER),可以使用类型定义:

将类型编号创建为数字

下一个快照将允许在设置标志时实现 NUMBER(N) 和 ORACLE 类型兼容性的其他方面。

http://hsqldb.org/support/ 下载

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


推荐