Java DBUnitを使ってみる

DBUnitってなんぞや~?JUnitでデータベースを扱うテストクラスを作成する際に利用されるライブラリのようです。

JavaプロジェクトからMavenプロジェクトに

初めから、Mavenプロジェクトで作成すれば良いのですが、Javaプロジェクトで始めてしまっているプロジェクトをMavenプロジェクトに変換できるか試してみました。

まずは、Javaプロジェクトを作成していきます。

f:id:ts0818:20170719183635j:plain

「プロジェクト名(P):」を入力し、「完了(F):」をクリック。

f:id:ts0818:20170719183636j:plain

プロジェクト上で右クリックし、「構成」>「Mavenプロジェクトへ変換」を選択。

f:id:ts0818:20170719183637j:plain

デフォルトの状態で「完了(F)」をクリック。

f:id:ts0818:20170719183638j:plain

Mavenプロジェクトに変換されました。pom.xmlを編集していきます。 

f:id:ts0818:20170719183639j:plain

pom.xml 変更前

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>DBUnitSample</groupId>
  <artifactId>DBUnitSample</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.5.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

pom.xml 変更後

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>DBUnitSample</groupId>
  <artifactId>DBUnitSample</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.5.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.dbunit</groupId>
      <artifactId>dbunit</artifactId>
      <version>2.4.3</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.5.6</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-nop</artifactId>
      <version>1.5.6</version>
    </dependency>
    <dependency>
      <groupId>com.h2database</groupId>
      <artifactId>h2</artifactId>
      <version>1.4.190</version>
    </dependency>
  </dependencies>
</project>

Maven 依存関係」に必要なライブラリが追加されます。

f:id:ts0818:20170719183651j:plain

今回は、テスト用のデータベースとしてH2というものを使用するのですが、GUIツールでSQLの発行などができるようです。

『C:¥Users¥Toshinobu¥.m2¥repository¥com¥h2database¥h2¥1.4.190¥h2-1.4.190.jar』をコマンドプロンプトで、javaコマンドで実行します。

cd C:¥Users¥ユーザー名¥.m2¥repository¥com¥h2database¥h2¥1.4.190
java -jar h2-1.4.190.jar

f:id:ts0818:20170719183642j:plain

バージョンなどは、インストールしたものに合わせてください。実行されると、ブラウザにGUIツールが表示されるので、そのまま「接続」をクリックします。

f:id:ts0818:20170719183641j:plain

管理画面に遷移します。

f:id:ts0818:20170719183643j:plain

SQLでテーブルを作成します。

CREATE TABLE user(
  userID varchar(10) PRIMARY KEY,
  name varchar(100),
  age int(3)
)

f:id:ts0818:20170719183644j:plain

f:id:ts0818:20170719183646j:plain ボタンをクリックして、SQLを実行します。テーブルが作成されました。 

f:id:ts0818:20170719220031p:plain

テスト用のデータを、xmlファイルに保存します。Eclipseのプロジェクトの中の「src」フォルダ上で右クリックし、「新規」>「フォルダ」を選択。

f:id:ts0818:20170719183647j:plain

「test」フォルダを作成し、「test」フォルダ上で右クリックし、「新規」>「フォルダ」を選択。「resources」フォルダを作成し、「resources」フォルダ上で右クリックし、「新規」>「ファイル」を選択し、「user_data.xml」ファイルを作成。

f:id:ts0818:20170720211354j:plain

 「user_data.xml」ファイルを編集。

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
  <user userid="0001" name="テスト一郎" age="39"/>
  <user userid="0002" name="テスト二郎" age="37"/>
  <user userid="0003" name="テスト三郎" age="33"/>
</dataset>    

テスト対象のクラスを作成していきます。

エンティティクラスとDAOクラスの2つのクラスを作っていきます。

エンティティクラス

package test;

public class User {
  private String userid;
  private String name;
  private int age;

  public String getUserid() {
    return userid;
  }

  public void setUserid(String userid) {
    this.userid = userid;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

}

続いて、DAOクラス

package test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class UserDAO {
  String url = "jdbc:h2:tcp://localhost/~/test";
  String dbuser = "sa";
  String password = "";

  public User findByUserid(String userid) {
	try {
	  Class.forName("org.h2.Driver")	;
	} catch(ClassNotFoundException e) {
	  e.printStackTrace();
	}

	User user = new User();
	String sql = "SELECT * FROM USER WHERE USERID = ?";
	// testデータベースにsaユーザー(パスワードなし)でH2DBに接続
	try(Connection conn = DriverManager.getConnection(url, dbuser, password);
		PreparedStatement pstmt = conn.prepareStatement(sql)) {
		pstmt.setString(1, userid);
		ResultSet res = pstmt.executeQuery();
		while(res.next()) {
		  user.setUserid(res.getString("USERID"));
		  user.setName(res.getString("NAME"));
		  user.setAge(res.getInt("AGE"));
		}

		res.close();
		pstmt.close();
	} catch(SQLException e) {
	  e.printStackTrace();
	}
	return user;
  }
}
    

テストクラスを作成していきます。 

package test;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;

import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.operation.DatabaseOperation;
import org.junit.Before;
import org.junit.Test;

public class UserDAOTest {
  String url = "jdbc:h2:tcp://localhost/~/test";
  String user = "sa";
  String password = "";

  @Before
  public void setUp() throws Exception {
    // DbUnit用のデータベース接続
    IDatabaseConnection dbConnection = null;
    Class.forName("org.h2.Driver");

    // testデータベースにsaユーザ(パスワードなし)でH2DB接続
    try(Connection conn = DriverManager.getConnection(url, user, password)) {
	    dbConnection = new DatabaseConnection(conn);

	    //
	    IDataSet dataSet = new FlatXmlDataSet(
			  new FileInputStream("src/test/resources/user_data.xml"));
	    // テスト用データをテーブルに挿入
	    DatabaseOperation.CLEAN_INSERT.execute(dbConnection, dataSet);
    }
  }

  @Test
  public void testFindByUserid() {
    UserDAO userDao = new UserDAO();
    User user = userDao.findByUserid("0001");

    // テスト結果の検証
    assertThat(user.getName(), is("テスト一郎"));
  }

}

JUnitテスト実行。

f:id:ts0818:20170719183652j:plain

 @Before アノテーションがついているところは、テスト実行前に実行されるので、ここで、テスト用のデータベースに接続して、テストデータを作成しておいたテスト用のデータベースのテーブルにセットしたりしてるようです。

@Test アノテーションがついてるところで、実際にテストが実行される流れかと思われます。

う~ん、テストを考えるのは難しいですね。

広告を非表示にする