web-dev-qa-db-ja.com

javaでjdbcコードを単体テストするにはどうすればよいですか?

データベースに接続し、1つ以上のクエリを実行して、結果を処理するコードの単体テストを作成したいと思います。 (実際にデータベースを使用せずに)

ここで別の開発者は、xml構成ファイルに基づいて対応するオブジェクトを返す独自のDataSource、Connection、Statement、PreparedStatement、およびResultSet実装を作成しました。 (偽のデータソースを使用し、それが返す結果セットに対してテストを実行することもできます)。

ここで車輪を再発明しますか?このようなものはユニットテスト用にすでに存在しますか? jdbcコードをテストする他の/より良い方法はありますか?

44
ScArcher2

DBUnit[〜#〜] hsqldb [〜#〜] と組み合わせて使用​​すると、たとえばCSVファイルから初期データを読み取ることができます。

24
WMR

いくつかのオプションがあります:

  • Mockライブラリを使用してデータベースをモックします。 JMock 。これの大きな欠点は、クエリとデータがまったくテストされない可能性が高いことです。
  • [〜#〜] hsqldb [〜#〜] など、テストには軽量データベースを使用します。クエリが単純な場合、これがおそらく最も簡単な方法です。
  • データベースをテスト専用にします。 DBUnit は良いオプションです。または、Mavenを使用している場合は、 sql-maven-plugin を使用して、データベースを適切にセットアップおよび破棄することもできます(注意してください)テスト間の依存関係)。このオプションは、クエリがデータベースベンダーで適切に機能するという最大の自信を与えるため、お勧めします。

これらのテストがデータベースが利用可能な場合にのみ実行されるように、これらのテストを構成可能にすることが必要かつ有用な場合があります。これは、たとえばビルドプロパティ。

30
Tatu Lahtela

私は次の組み合わせを使用したい:

DBUnitとHSQLDBを使用するだけで、かなり遠くまで到達できます。 Unitilsは、データベースの状態を管理およびリセットするためのコードの最後のマイルを提供します。また、データベーススキーマの変更を管理する優れた方法を提供し、特定のRBDMS(Oracle、DB2、SQL Serverなど)を簡単に使用できるようにします。最後に、Unitilsは、APIを近代化し、DBUnitの操作をより快適にするDBUnitのニースラッパーを提供します。

ユニティルをまだチェックアウトしていない場合は、絶対にすべきです。ユニティルはしばしば見過ごされ、過小評価されています。

8
Jim Hurne

このようなタスクには、Mockフレームワークを使用します。 ( jMocketc

一部

6
Sunny Milenov

derby (現在はJavaDBと呼ばれる)または sqlite があるのは、これらが比較的迅速かつ簡単に作成、ロード、テスト、および破壊できる、小さくてシンプルなデータベースである理由です。

4
S.Lott

それほど簡単ではないコードをテストするために、 EasyMock を使用することを好みます。

2
folone

HSQLがユニットテスト中の方法であると思います。テストのポイントは、jdbcコードをテストして、動作することを確認することです。カスタムクラスを追加するかjdbc呼び出しをモックすると、バグを簡単に隠すことができます。

私は主にmysqlを使用し、テストがドライバークラスを実行し、urlがorg.hsqldb.jdbcDriverおよびjdbc:hsqldb:mem:testに変更されるときに使用します。

2
user30684

統合テストではなく単体テストを実行する場合は、次のように、Mockitoのみを使用して、非常に基本的で単純なアプローチを使用できます。

public class JDBCLowLevelTest {

    private TestedClass tested;
    private Connection connection;
    private static Driver driver;

    @BeforeClass
    public static void setUpClass() throws Exception {
        // (Optional) Print DriverManager logs to system out
        DriverManager.setLogWriter(new PrintWriter((System.out)));

        // (Optional) Sometimes you need to get rid of a driver (e.g JDBC-ODBC Bridge)
        Driver configuredDriver = DriverManager.getDriver("jdbc:odbc:url");

        System.out.println("De-registering the configured driver: " + configuredDriver);
        DriverManager.deregisterDriver(configuredDriver);

        // Register the mocked driver
        driver = mock(Driver.class);
        System.out.println("Registering the mock driver: " + driver);
        DriverManager.registerDriver(driver);
    }

    @AfterClass
    public static void tearDown() throws Exception {
        // Let's cleanup the global state
        System.out.println("De-registering the mock driver: " + driver);
        DriverManager.deregisterDriver(driver);
    }

    @Before
    public void setUp() throws Exception {
        // given
        tested = new TestedClass();

        connection = mock(Connection.class);

        given(driver.acceptsURL(anyString())).willReturn(true);
        given(driver.connect(anyString(), Matchers.<Properties>any()))
                .willReturn(connection);

        given(connection.prepareCall(anyString())).willReturn(statement);        
    }
}

他のMockitoテストのように、さまざまなシナリオをテストできます。

@Test
public void shouldHandleDoubleException() throws Exception {
    // given
    SomeData someData = new SomeData();

    given(connection.prepareCall(anyString()))
            .willThrow(new SQLException("Prepare call"));
    willThrow(new SQLException("Close exception")).given(connection).close();

    // when
    SomeResponse response = testClass.someMethod(someData);

    // then
    assertThat(response, is(SOME_ERROR));
}
1
Paweł Prażak

アプリケーションでjdbcをモックする方法は、もちろん実際のjdbcトランザクションの実装方法に依存します。

Jdbcをそのまま使用している場合は、DBUtils.getMetadataFor(String tablename)の行でいくつかのタスクを実行するための一種のユーティリティクラスを自分で作成したと思います。これが意味することは、そのクラスのモックを作成する必要があり、それがあなたが必要とするすべてである可能性があるということです。すでに一連のjdbc関連のモックオブジェクトが利用可能になっているので、これはかなり簡単なソリューションです。私はあなたのjdbcコードがアプリケーション全体で爆発しないと仮定していることに注意してください-もしそうなら、リファクタリング!!!

ただし、データベース処理用のフレームワーク(Spring FrameworkのJDBCテンプレートクラスなど)を使用している場合は、EasyMockまたはその他の同等物を使用してインターフェイスクラスをモックできます。そうすれば、接続を簡単にモックするために必要な世界のすべてのパワーを手に入れることができます。

最後に、他に何も機能しない場合は、他の人がすでに言ったことを実行し、DBUnitやダービーを使用できます。

1
P Arrayah

DBUnit があります。データベースなしでjdbcコードをテストすることはできませんが、データベースをエミュレートすることで別の購入セットを導入できるようです。

1
Steve K

Acolyteドライバーを使用して、JDBC接続をモックアップし、テスト中にそれを管理し、結果セットとしてデータを返します(タイプセーフな行リストAPIを使用): https://github.com/cchantep/acolyte

注:私はAcolyteの著者です。

0
cchantep

JDBDTをご覧ください: http://jdbdt.org

DBUnitの代替として、データベースのセットアップとアサーションに使用できます。

注:私はJDBDTの著者です。

0
edrdo

Mockrunnerを使用します。 http://mockrunner.sourceforge.net/ モック接続とデータソースが組み込まれているため、自分で実装する必要はありません。

0
grbonk