LoginSignup
3
3

More than 5 years have passed since last update.

H2 + DbSetupでのcsvによるテストデータのロード

Posted at

背景

DbSetupはJavaのユニットテストでDBに初期データをロードするのに非常に便利なライブラリです。ただし、大量データや多数の列からなるデータのロードには適しておらず、その場合にはDbUnit等が便利と思われます。これはDbSetupの前提条件である「ユニットテストで必要となるテストデータは大して多くない」というものの現れであり、実際その通りなので、欠点ではありません。

しかしながら、ある種の集計機能だとか、ユニットテストの可読性がテストデータをCSVなど外部ファイルに残した方が見やすい、というケースが稀に発生します。その場合のためだけにDbUnitとか使うのもだるいので、DbSetupだけで済ませる方法は何かないか、と考えました。

解決案

今回取った方法としては、まずテストデータは素直にcsvファイルにします。それから、そのテストデータをH2 Database EngineCSVREAD関数で読み込み、データロードを行うINSERT INTO ... SELECT * FROM CSVREAD(...)
のSQLを、DbSetupで生のSQLを実行できるOperations#sqlに渡します。

ソースコード

クラスパスの通っている場所に適当なファイルを作ります。

src\test\resources\hoge.csv
1,かがみ
2,ほげ
3,foo
4,bar
5,piyo

pom.xmlに依存性を追加します。

pom.xml
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.192</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.ninja-squad</groupId>
            <artifactId>DbSetup</artifactId>
            <version>2.1.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

ソースコード。

package kagamihoge.dbsetupwithh2csvread;

import static com.ninja_squad.dbsetup.Operations.sequenceOf;
import static com.ninja_squad.dbsetup.Operations.sql;

import java.net.URL;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import org.junit.Before;
import org.junit.Test;

import com.ninja_squad.dbsetup.DbSetup;
import com.ninja_squad.dbsetup.destination.DriverManagerDestination;
import com.ninja_squad.dbsetup.operation.Operation;

public class HogeTest {

    @Before
    public void setUp() throws Exception {
        URL csvResource = getClass().getClassLoader().getResource("hoge.csv");
        Path csv = Paths.get(csvResource.toURI()).toAbsolutePath();

        Operation operation = sequenceOf(
                sql("CREATE TABLE hoge(hogeid VARCHAR(16) PRIMARY KEY NOT NULL, hogename VARCHAR(100))"),
                sql("INSERT INTO hoge(hogeid, hogename) SELECT * FROM CSVREAD('" + csv + "','hogeid, hogename','UTF-8')"));

        DbSetup dbSetup = new DbSetup(
                new DriverManagerDestination("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", "sa", ""), operation);
        dbSetup.launch();
    }

    @Test
    public void test1() throws SQLException {
        // 注意:エラー処理・DBのクローズ処理が適当なので、適宜読み替えて下さい。
        Connection con = DriverManager.getConnection("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", "sa", "");
        Statement st1 = con.createStatement();

        ResultSet rs = st1.executeQuery("SELECT hogeid, hogename FROM hoge");
        while (rs.next()) {
            System.out.println(rs.getString(1) + "," + rs.getString(2));
        }

        st1.close();
        con.close();
    }
}

setUpの最初では、CSVREAD関数に渡すファイルの絶対パスを取得するため、クラスパス上に配置したテストデータのCSVファイル(hoge.csv)から絶対パスを取得しています。

そのあと、DbSetupのOperations#sqlでINSERT INTO ... SELECT * FROM CSVREAD(...)を実行することで、テストデータのロードを行います。

参考文献

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3