Fight the Future

Java言語とJVM、そしてJavaエコシステム全般にまつわること

IT勉強会での初プレゼンなどお助けします!

勉強会でスピーカーをやりたいけど、プレゼンが初めて、苦手という方に無償でコーチできます。スライドのレビューや録画したリハへのアドバイスなどなど。Twitter@jyukutyoまでメンションでもDMでもお気軽にご連絡ください。

私はIT講師の経験があり、プレゼンはデブサミやJJUG CCCなど200人規模の経験が豊富で最大800人の前でプレゼンしました。海外ではDevoxxUSで。デブサミ2017では公募スピーカー1位、デブサミ関西2012アワードで5位となりました。

TestNGとDbUnitを連携したサンプル

TestNGDbUnitを連携させることで、テストクラスはTestCaseを継承する必要がなくなる。
TestCaseを継承する代わりに、XXDatabaseTesterというDbUnitにあるクラスを使う。

  • JdbcDatabaseTester
  • DataSourceDatabaseTester

DriverManagerからConnectionを作るか、DataSourceからConnectionを作るかで使い分ける。


たとえばテスト実行前のsetup処理はこんな感じ。

	@BeforeClass
	@Parameters( { "driver", "url", "username", "password" })
	public void initialize(String driver, String url, String username,
			String password) throws Exception {

		JdbcDatabaseTester connectionHolder =
			new JdbcDatabaseTester(driver, url, username, password);
		IDataSet initialDataSet =
			new FlatXmlDataSet(new File("DbUnitSampleTestCase.xml"));
		IDatabaseConnection connection = connectionHolder.getConnection();
		try {
			DatabaseOperation.CLEAN_INSERT.execute(connection, initialDataSet);
		} finally {
			connection.close();
		}
	}

まずアノテーションから。両方ともTestNGアノテーション

@BeforeClassはsetup処理をするメソッドにつける。この場合クラスで1回(メソッドごとではない)呼び出される。

@Parametersはこのメソッドに渡す引数の値を指定する。ただし、"driver"という値を渡しているわけではなくて、これはキーである。
実際の値はTestNGのテスト実行ファイルに記述している。たとえばこんな感じ。

	<parameter name="driver" value="com.mysql.jdbc.Driver"></parameter>
	<parameter name="url" value="jdbc:mysql://127.0.0.1/データベース名"></parameter>
	<parameter name="username" value="ユーザー名"></parameter>
	<parameter name="password" value="パスワード"></parameter>

このパラメータを使ってJdbcDatabaseTesterオブジェクトを生成する。
さらに、データベースに登録する初期データを読みこんでる。

		IDataSet initialDataSet =
			new FlatXmlDataSet(new File("DbUnitSampleTestCase.xml"));

これはDbUnitの機能。DbUnitSampleTestCase.xmlはデータを記述したXMLファイルだ。
このファイルからDataSetオブジェクトを生成する。DataSetはTableを(複数)保持している。


そしてJdbcDatabaseTesterから(DbUnitの)Connectionを取得し、初期データを登録する。

		try {
			DatabaseOperation.CLEAN_INSERT.execute(connection, initialDataSet);
		} finally {
			connection.close();
		}

DatabaseOperationはデータの登録方法で、今回は定数CLEAN_INSERTを利用した。
CLEAN_INSERTはDELETE文ですべてのレコードを削除してからINSERT文を発行してデータを登録する。
これでsetup処理は完了。


テストメソッドはこんな感じ。

	@Test
	public void verifySelectAllFromDept() {
		DeptDao deptDao = new DeptDao();
		List<Dept> actual = deptDao.listAllDept();
		assertEquals(actual.size(), 4);
	}

@TestはTestNGアノテーションでテストメソッドを表す。
テスト対象メソッドを呼び出して、assertEquals()を呼び出す。
継承していないので、assertEquals()はstatic importしてる。


完全なソースはここから。

package net.kronos_jp.dbtest.sample;

import static org.testng.Assert.assertEquals;

import java.io.File;
import java.util.List;

import net.kronos_jp.dbtest.target.dao.DeptDao;
import net.kronos_jp.dbtest.target.entity.Dept;

import org.dbunit.JdbcDatabaseTester;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.operation.DatabaseOperation;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

/**
 * <p>
 * DbUnitTestNGを連携したサンプルです。
 * </p>
 * 
 * @author jyukutyo
 * 
 */
@Test
public class DbUnitSampleTestCase {

	@BeforeClass
	@Parameters( { "driver", "url", "username", "password" })
	public void initialize(String driver, String url, String username,
			String password) throws Exception {

		JdbcDatabaseTester connectionHolder =
			new JdbcDatabaseTester(driver, url, username, password);
		IDataSet initialDataSet =
			new FlatXmlDataSet(new File("DbUnitSampleTestCase.xml"));
		IDatabaseConnection connection = connectionHolder.getConnection();
		try {
			DatabaseOperation.CLEAN_INSERT.execute(connection, initialDataSet);
		} finally {
			connection.close();
		}
	}

	@Test
	public void verifySelectAllFromDept() {
		DeptDao deptDao = new DeptDao();
		List<Dept> actual = deptDao.listAllDept();
		assertEquals(actual.size(), 4);
	}

}