Oracle インスタンスからメモリ内データベース構造を作成する
-
05-10-2019 - |
質問
たくさんのアプリケーションがあります "ユニット" テストは実行中に Oracle データベースへの実際の接続を使用します。
ご想像のとおり、これらのテストはいくつかの Spring コンテキストを初期化し、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、Spring 2.5、Oracle 10.g、Maven 2
編集
私の単体テストに関する情報:
私が使用したアプリケーションでは hsqldb
, 以下のような検査を受けました。- DB とは関係のないいくつかの「基本的な」単体テスト。- DAOのテストには、次を使用しました hsqldb
CRUDなどのデータベース操作を実行します。- 次に、サービス層で使用しました Mockito
アプリケーション全体ではなくサービスのテストに焦点を当てるために、DAO オブジェクトをモックします (つまり、サービス + dao + DB)。
現在のアプリケーションでは、最悪のシナリオが考えられます。DAO 層のテストを実行するには、Oracle 接続が必要です。サービス層は次のことを行います ない DAO をシミュレートするには、(まだ) モック オブジェクトを使用します。したがって、サービスのテスト また Oracle 接続が必要です。
モックとメモリ内データベースは 2 つの別個のポイントであることは承知しており、できるだけ早く対処するつもりです。ただし、私の最初のステップは、 試す インメモリデータベースによる Oracle 接続を削除するには、 Mockito
テストを強化するための知識。
単体テストを統合テストから分離したいことにも注意してください。後者は、「実際の」テストを実行するために Oracle データベースにアクセスする必要がありますが、私の主な懸念 (そしてこれがこの質問の目的です) は、現在、ほとんどすべての単体テストが単独で実行されていないことです。
解決
テストにはインメモリ/Java データベースを使用します。これにより、テストでデータベースを「抽象化」しようとする場合よりも、テストが現実世界に近づくことが保証されます。おそらく、そのようなテストは作成と保守も容易になります。一方、UI テストは通常、自動化が難しいため、テストで「抽象化」したいと考えられるのは UI です。
あなたが投稿した Oracle 構文は H2 データベースでうまく機能するため (私がテストしたばかりです)、H2 は HSQLDB よりも Oracle 構文をサポートしているようです。免責事項:私は H2 の著者の 1 人です。何かが動作しない場合は、H2 メーリング リストに投稿してください。
いずれにせよ、バージョン管理システムにデータベースの DDL ステートメントが必要です。これらのスクリプトはテストにも使用できます。場合によっては、複数のスキーマ バージョンをサポートする必要がある場合もあります。その場合は、バージョン更新スクリプト (alter table...) を作成できます。Java データベースを使用すると、それらもテストできます。
ちなみに、H2やHSQLDBを使う場合は必ずしもインメモリモードを使う必要はありません。どちらのデータベースも、データを永続化しても高速です。また、インストールが簡単 (jar ファイルのみ) で、必要なメモリが Oracle よりもはるかに少なくなります。
他のヒント
最新のHSQLDB 2.0.1は、構文互換性フラグ、sql.syntax_ora = trueを介して、デュアル、rownum、nextval、および通貨のOracle構文をサポートしています。同様に、一意の制約におけるヌル文字列とnullの制限を備えた文字列の連結は、他のフラグで処理されます。 to_char、to_date、nvlなどのほとんどのOracle関数はすでに組み込まれています。
現時点では、番号などの単純なOracleタイプを使用するには、タイプ定義を使用できます。
数値としてタイプ番号を作成します
次のスナップショットでは、フラグが設定されているときに数字(n)およびOracleタイプの互換性の他の側面が許可されます。
からダウンロードしてください http://hsqldb.org/support/
更新:] 10月4日に発行されたスナップショットは、ほとんどのOracle固有のタイプをANSI SQLタイプに変換します。 HSQLDB 2.0は、Oracleと同じようにANSI SQL間隔タイプと日付 /タイムスタンプ算術もサポートしています。
あなたのユニットテストは何のためですか? DDLの適切な動作とストアドプロシージャのテストをテストする場合は、Oracleに「近い」テストを作成する必要があります。Javaコードなしで、またはSpringやその他の素敵なWebインターフェイスなしで、DBに焦点を当てています。
JavaとSpringで実装されているアプリケーションロジックをテストする場合は、Mock Objects/Database接続を使用して、テストをデータベースから独立させることができます。
動作全体をテストしたい場合(モジュラー開発とテストの原則に反するもの)、厄介な不可逆的な変更を行うリスクがなくても、データベースを仮想化し、そのインスタンスでテストすることができます。
テストが自分自身をクリーンアップする限り(すでにセットアップの方法を知っているように見えますが)、実際のデータベースインスタンスに対してテストを実行することには何の問題もありません。実際、それは私が通常好むアプローチです。なぜなら、あなたはできるだけ生産に近いものをテストするからです。
互換性は小さく見えますが、実際にはそれほど長くは噛み付きません。良いケースでは、いくつかの厄介なSQL翻訳 /広範なock笑で逃げることができます。悪い場合、システムの一部をテストすることは不可能です。これは、ビジネス批判的なシステムの容認できないリスクだと思います。