ネットの検索結果でチラチラとは見ていたのですが、この度初めて自分でもDBUnitを使ってみました。ネット上のサンプルコードをほとんどそのまま実行しただけですが、私の手元でも簡単にユニットテスト用のDBとデータを準備することができました。
従来、H2 DatabaseはRunScriptで初期化用のスキーマを流し込んでいたのですが、これならJDBCドライバを選ばない気がします。
※ 他のJDBCドライバでH2 DatabaseのINIT=RunScript相当の機能が可能なのか知りません。
##環境
- DBUnit 2.5.1
- JUnit 4.12
ユニットテストのコード(パクリですが)
以下のような感じです。Excelファイルもデータソースとして使える点は、仕事でプログラムを作る人にとってかなりのアドバンテージな気がします。
PersonRepositoryTest.java
import java.io.File;
import org.junit.*;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
import static org.h2.engine.Constants.UTF8;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
import javax.sql.DataSource;
import org.dbunit.IDatabaseTester;
import org.dbunit.JdbcDatabaseTester;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.excel.XlsDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.dbunit.operation.DatabaseOperation;
import org.h2.jdbcx.JdbcDataSource;
import org.h2.tools.RunScript;
public class PersonRepositoryTest {
private static final String JDBC_DRIVER = org.h2.Driver.class.getName();
private static final String JDBC_URL = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1";
private static final String USER = "sa";
private static final String PASSWORD = "";
@BeforeClass
public static void createSchema() throws Exception {
RunScript.execute(JDBC_URL, USER, PASSWORD, "schema.sql", UTF8, false);
}
@Before
public void importDataSet() throws Exception {
IDataSet dataSet = readDataSet();
cleanlyInsert(dataSet);
}
private IDataSet readDataSet() throws Exception {
// return new FlatXmlDataSetBuilder().build(new File("dataset.xml"));
return new XlsDataSet(new File("dataset.xls"));
}
private void cleanlyInsert(IDataSet dataSet) throws Exception {
IDatabaseTester databaseTester = new JdbcDatabaseTester(JDBC_DRIVER, JDBC_URL, USER, PASSWORD);
databaseTester.setSetUpOperation(DatabaseOperation.CLEAN_INSERT);
databaseTester.setDataSet(dataSet);
databaseTester.onSetup();
}
@Test
public void findsAndReadsExistingPersonByFirstName() throws Exception {
PersonRepository repository = new PersonRepository(dataSource());
Person charlie = repository.findPersonByFirstName("Charlie");
assertThat(charlie.getFirstName(), is("Charlie"));
assertThat(charlie.getLastName(), is("Brown"));
assertThat(charlie.getAge(), is(42));
}
@Test
public void returnsNullWhenPersonCannotBeFoundByFirstName() throws Exception {
PersonRepository repository = new PersonRepository(dataSource());
Person person = repository.findPersonByFirstName("iDoNotExist");
assertThat(person, is(nullValue()));
}
private DataSource dataSource() {
JdbcDataSource dataSource = new JdbcDataSource();
dataSource.setURL(JDBC_URL);
dataSource.setUser(USER);
dataSource.setPassword(PASSWORD);
return dataSource;
}
}
build.gradle
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'provided-base'
buildscript {
repositories {
maven { url 'http://jcenter.bintray.com' }
}
dependencies {
classpath 'com.netflix.nebula:gradle-extra-configurations-plugin:1.12.+'
}
}
sourceCompatibility = "$project.java_version"
targetCompatibility = "$project.java_version"
version = "$project.spec_version"
group = "$project.app_group"
repositories {
maven { url "http://repo.maven.apache.org/maven2" }
}
dependencies {
provided 'org.projectlombok:lombok:1.16.+'
compile("com.h2database:h2:1.4.+")
// Logging
compile('ch.qos.logback:logback-classic:1.1.+')
compile('org.slf4j:slf4j-api:1.7.+')
compile('org.slf4j:jcl-over-slf4j:1.7.+')
compile('org.slf4j:log4j-over-slf4j:1.7.+')
testCompile 'junit:junit:4.11', {
transitive = false
}
testCompile 'org.hamcrest:hamcrest-all:1.3'
testCompile 'org.dbunit:dbunit:2.5.+'
}
def defaultEncoding = 'UTF-8'
tasks.withType(JavaCompile) {
options.encoding = defaultEncoding
}
jar {
manifest {
attributes 'Implementation-Title': "$project.app_description",
// 'Main-Class': "org.gradle.Main",
'Implementation-Version': version + "-$project.patch_version"
}
}
clean {
delete 'bin', 'target', 'logs'
}
task(runMain, dependsOn: 'classes', type: JavaExec) {
main = 'org.gradle.Main'
classpath = sourceSets.main.runtimeClasspath
standardInput= System.in
}
defaultTasks 'runMain'
schema.sql
create table if not exists PERSON (
ID int identity primary key,
NAME varchar,
LAST_NAME varchar,
AGE smallint,
);
dataset.xml
<dataset>
<PERSON NAME="Bob" LAST_NAME="Doe" AGE="18"/>
<PERSON NAME="Alice" LAST_NAME="Foo" AGE="23"/>
<PERSON NAME="Charlie" LAST_NAME="Brown" AGE="42"/>
</dataset>