JUnit5 DBUnitを利用して、DML(insert文, update文, delete文)を実行すると、どのDB上で実行した場合でも、テスト実行後にロールバックされる。
今回は、JUnit5 DBUnitを利用して、各DB上でDML文を実行した時の動きを確認してみたので、そのサンプルプログラムを共有する。
前提条件
下記記事の実装が完了していること。
また、下記記事のように、A5M2を利用して各DBに接続できていること。
やってみたこと
- 作成したサンプルプログラムの構成
- Oracleの場合のソースコードとテスト実行結果
- MySQLの場合のソースコードとテスト実行結果
- PostgreSQLの場合のソースコードとテスト実行結果
- SQL Serverの場合のソースコードとテスト実行結果
作成したサンプルプログラムの構成
作成したサンプルプログラムの構成は以下の通り。

なお、上記の赤枠は、前提条件のプログラムから追加・変更したプログラムである。
databaseSetupTest.xlsx、expectedDatabaseTest.xlsxは、各DB上でのテストを行うUserDataDmlTestXXX.javaで利用するデータで、テスト実行前に設定するデータをdatabaseSetupTest.xlsxで、テスト実行後の想定データを設定するデータをexpectedDatabaseTest.xlsxで、それぞれ定義している。
また、上記赤枠以外のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/junit5-dbunit-dml/demo
Oracleの場合のソースコードとテスト実行結果
テスト対象となるMapperの内容は、以下の通り。
package com.example.demo.mapper.ora;
import com.example.demo.mapper.UserData;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserDataMapperOra {
/**
* Oracleでユーザーデータテーブル(user_data)の全データを取得する
* @return ユーザーデータテーブル(user_data)の全データ
*/
List<UserData> findAll();
/**
* Oracleでユーザーデータテーブル(user_data)の全データを削除する
*/
void truncateUserData();
/**
* Oracleで指定したユーザーデータテーブル(user_data)のデータを追加する
* @param userData ユーザーデータテーブル(user_data)の追加データ
*/
void create(UserData userData);
/**
* Oracleで指定したユーザーデータテーブル(user_data)のデータを更新する
* @param userData ユーザーデータテーブル(user_data)の更新後データ
*/
void update(UserData userData);
/**
* Oracleで指定したIDをもつユーザーデータテーブル(user_data)のデータを削除する
* @param id ID
* @return ユーザーデータテーブル(user_data)の指定したIDのデータ
*/
void deleteById(Long id);
}<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.ora.UserDataMapperOra">
<resultMap id="userDataResultMap" type="com.example.demo.mapper.UserData" >
<id column="id" property="id" jdbcType="BIGINT" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="birthY" property="birthY" jdbcType="VARCHAR" />
<result column="birthM" property="birthM" jdbcType="VARCHAR" />
<result column="birthD" property="birthD" jdbcType="VARCHAR" />
<result column="sex" property="sex" jdbcType="VARCHAR" />
<result column="memo" property="memo" jdbcType="VARCHAR" />
<result column="sex_value" property="sex_value" jdbcType="VARCHAR" />
</resultMap>
<select id="findAll" resultMap="userDataResultMap">
SELECT
id
, name
, birth_year as birthY
, birth_month as birthM
, birth_day as birthD
, sex
, memo
, CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE ''
END AS sex_value
FROM USER_DATA
</select>
<update id="truncateUserData">
TRUNCATE TABLE USER_DATA
</update>
<insert id="create" parameterType="com.example.demo.mapper.UserData">
INSERT INTO USER_DATA (
id
, name
, birth_year
, birth_month
, birth_day
, sex
, memo
) VALUES (
#{id}
, #{name}
, #{birthY}
, #{birthM}
, #{birthD}
, #{sex}
, #{memo,jdbcType=VARCHAR}
)
</insert>
<update id="update" parameterType="com.example.demo.mapper.UserData">
UPDATE USER_DATA SET name = #{name}, birth_year = #{birthY}
, birth_month = #{birthM}, birth_day = #{birthD}
, sex = #{sex}, memo = #{memo,jdbcType=VARCHAR}
WHERE id = #{id}
</update>
<delete id="deleteById" parameterType="java.lang.Long">
DELETE FROM USER_DATA WHERE id = #{id}
</delete>
</mapper>また、Mapperのテストクラスの内容は以下の通りで、DML(insert文, update文, delete文)実行後の結果を検証している。
package com.example.demo.mapper.ora;
import com.example.demo.mapper.DemoXlsDataSetLoader;
import com.example.demo.mapper.UserData;
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.TransactionDbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.github.springtestdbunit.annotation.DbUnitConfiguration;
import com.github.springtestdbunit.annotation.ExpectedDatabase;
import com.github.springtestdbunit.assertion.DatabaseAssertionMode;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import java.util.List;
// JUnit5ベースでMyBatisのテストを実行する
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class
, DirtiesContextTestExecutionListener.class
, TransactionDbUnitTestExecutionListener.class
, DbUnitTestExecutionListener.class})
@DbUnitConfiguration(dataSetLoader = DemoXlsDataSetLoader.class
, databaseConnection = {"dbUnitDatabaseConnectionOra"})
public class UserDataDmlTestOra {
/**
* ユーザーデータテーブル(user_data)へアクセスするマッパー
*/
@Autowired
private UserDataMapperOra userDataMapperOra;
/**
* 各テストメソッドを実行する前に行う処理を定義する.
*/
@BeforeEach
public void beforeTest() {
System.out.println();
System.out.println("*** UserDataDmlTestOraクラス テスト結果 start ***");
}
/**
* DML(insert,update,delete)文の実行結果を検証する.
*/
@Test
@DatabaseSetup("/com/example/demo/xls/databaseSetupTest.xlsx")
@ExpectedDatabase(value = "/com/example/demo/xls/expectedDatabaseTest.xlsx"
, assertionMode = DatabaseAssertionMode.NON_STRICT_UNORDERED)
public void userDataTest() {
// ユーザーデータ追加・更新・削除する前のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ DML実行前 ***");
List<UserData> userDataList = userDataMapperOra.findAll();
for (UserData userData : userDataList) {
System.out.println(userData);
}
System.out.println();
// ユーザーデータ(ID=4)を追加
UserData userData4 = new UserData(4, "テスト プリン4"
, 2016, 5, 6, "1", "テスト4", "");
userDataMapperOra.create(userData4);
// ユーザーデータ(ID=3)を更新
UserData userData3 = new UserData(3, "テスト プリン3更新後"
, 2015, 4, 21, "2", "テスト3更新後", "");
userDataMapperOra.update(userData3);
// ユーザーデータ(ID=2)を削除
userDataMapperOra.deleteById(2L);
// ユーザーデータ追加・更新・削除した後のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ DML実行後 ***");
userDataList = userDataMapperOra.findAll();
for (UserData userData : userDataList) {
System.out.println(userData);
}
}
/**
* 各テストメソッドを実行した後に行う処理を定義する.
*/
@AfterEach
public void afterTestClass() {
System.out.println("*** UserDataDmlTestOraクラス テスト結果 end ***");
System.out.println();
}
}上記テストクラスの実行結果は以下の通りで、DML(insert文, update文, delete文)実行でロールバックされていることが確認できる。
MySQLの場合のソースコードとテスト実行結果
テスト対象となるMapperの内容は、以下の通り。
package com.example.demo.mapper.ms;
import com.example.demo.mapper.UserData;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserDataMapperMs {
/**
* MySQLでユーザーデータテーブル(user_data)の全データを取得する
* @return ユーザーデータテーブル(user_data)の全データ
*/
List<UserData> findAll();
/**
* MySQLでユーザーデータテーブル(user_data)の全データを削除する
*/
void truncateUserData();
/**
* MySQLで指定したユーザーデータテーブル(user_data)のデータを追加する
* @param userData ユーザーデータテーブル(user_data)の追加データ
*/
void create(UserData userData);
/**
* MySQLで指定したユーザーデータテーブル(user_data)のデータを更新する
* @param userData ユーザーデータテーブル(user_data)の更新後データ
*/
void update(UserData userData);
/**
* MySQLで指定したIDをもつユーザーデータテーブル(user_data)のデータを削除する
* @param id ID
* @return ユーザーデータテーブル(user_data)の指定したIDのデータ
*/
void deleteById(Long id);
}<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.ms.UserDataMapperMs">
<resultMap id="userDataResultMap" type="com.example.demo.mapper.UserData" >
<id column="id" property="id" jdbcType="BIGINT" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="birthY" property="birthY" jdbcType="VARCHAR" />
<result column="birthM" property="birthM" jdbcType="VARCHAR" />
<result column="birthD" property="birthD" jdbcType="VARCHAR" />
<result column="sex" property="sex" jdbcType="VARCHAR" />
<result column="memo" property="memo" jdbcType="VARCHAR" />
<result column="sex_value" property="sex_value" jdbcType="VARCHAR" />
</resultMap>
<select id="findAll" resultMap="userDataResultMap">
SELECT
id
, name
, birth_year as birthY
, birth_month as birthM
, birth_day as birthD
, sex
, memo
, CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE ''
END AS sex_value
FROM USER_DATA
</select>
<update id="truncateUserData">
TRUNCATE TABLE USER_DATA
</update>
<insert id="create" parameterType="com.example.demo.mapper.UserData">
INSERT INTO USER_DATA (
id
, name
, birth_year
, birth_month
, birth_day
, sex
, memo
) VALUES (
#{id}
, #{name}
, #{birthY}
, #{birthM}
, #{birthD}
, #{sex}
, #{memo,jdbcType=VARCHAR}
)
</insert>
<update id="update" parameterType="com.example.demo.mapper.UserData">
UPDATE USER_DATA SET name = #{name}, birth_year = #{birthY}
, birth_month = #{birthM}, birth_day = #{birthD}
, sex = #{sex}, memo = #{memo,jdbcType=VARCHAR}
WHERE id = #{id}
</update>
<delete id="deleteById" parameterType="java.lang.Long">
DELETE FROM USER_DATA WHERE id = #{id}
</delete>
</mapper>また、Mapperのテストクラスの内容は以下の通りで、DML(insert文, update文, delete文)実行後の結果を検証している。
package com.example.demo.mapper.ms;
import com.example.demo.mapper.DemoXlsDataSetLoader;
import com.example.demo.mapper.UserData;
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.TransactionDbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.github.springtestdbunit.annotation.DbUnitConfiguration;
import com.github.springtestdbunit.annotation.ExpectedDatabase;
import com.github.springtestdbunit.assertion.DatabaseAssertionMode;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import java.util.List;
// JUnit5ベースでMyBatisのテストを実行する
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class
, DirtiesContextTestExecutionListener.class
, TransactionDbUnitTestExecutionListener.class
, DbUnitTestExecutionListener.class})
@DbUnitConfiguration(dataSetLoader = DemoXlsDataSetLoader.class
, databaseConnection = {"dbUnitDatabaseConnectionMs"})
public class UserDataDmlTestMs {
/**
* ユーザーデータテーブル(user_data)へアクセスするマッパー
*/
@Autowired
private UserDataMapperMs userDataMapperMs;
/**
* 各テストメソッドを実行する前に行う処理を定義する.
*/
@BeforeEach
public void beforeTest() {
System.out.println();
System.out.println("*** UserDataDmlTestMsクラス テスト結果 start ***");
}
/**
* DML(insert,update,delete)文の実行結果を検証する.
*/
@Test
@DatabaseSetup("/com/example/demo/xls/databaseSetupTest.xlsx")
@ExpectedDatabase(value = "/com/example/demo/xls/expectedDatabaseTest.xlsx"
, assertionMode = DatabaseAssertionMode.NON_STRICT_UNORDERED)
public void userDataTest() {
// ユーザーデータ追加・更新・削除する前のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ DML実行前 ***");
List<UserData> userDataList = userDataMapperMs.findAll();
for (UserData userData : userDataList) {
System.out.println(userData);
}
System.out.println();
// ユーザーデータ(ID=4)を追加
UserData userData4 = new UserData(4, "テスト プリン4"
, 2016, 5, 6, "1", "テスト4", "");
userDataMapperMs.create(userData4);
// ユーザーデータ(ID=3)を更新
UserData userData3 = new UserData(3, "テスト プリン3更新後"
, 2015, 4, 21, "2", "テスト3更新後", "");
userDataMapperMs.update(userData3);
// ユーザーデータ(ID=2)を削除
userDataMapperMs.deleteById(2L);
// ユーザーデータ追加・更新・削除した後のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ DML実行後 ***");
userDataList = userDataMapperMs.findAll();
for (UserData userData : userDataList) {
System.out.println(userData);
}
}
/**
* 各テストメソッドを実行した後に行う処理を定義する.
*/
@AfterEach
public void afterTestClass() {
System.out.println("*** UserDataDmlTestMsクラス テスト結果 end ***");
System.out.println();
}
}上記テストクラスの実行結果は以下の通りで、DML(insert文, update文, delete文)実行でロールバックされていることが確認できる。
PostgreSQLの場合のソースコードとテスト実行結果
テスト対象となるMapperの内容は、以下の通り。
package com.example.demo.mapper.ps;
import com.example.demo.mapper.UserData;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserDataMapperPs {
/**
* PostgreSQLでユーザーデータテーブル(user_data)の全データを取得する
* @return ユーザーデータテーブル(user_data)の全データ
*/
List<UserData> findAll();
/**
* PostgreSQLでユーザーデータテーブル(user_data)の全データを削除する
*/
void truncateUserData();
/**
* PostgreSQLで指定したユーザーデータテーブル(user_data)のデータを追加する
* @param userData ユーザーデータテーブル(user_data)の追加データ
*/
void create(UserData userData);
/**
* PostgreSQLで指定したユーザーデータテーブル(user_data)のデータを更新する
* @param userData ユーザーデータテーブル(user_data)の更新後データ
*/
void update(UserData userData);
/**
* PostgreSQLで指定したIDをもつユーザーデータテーブル(user_data)のデータを削除する
* @param id ID
* @return ユーザーデータテーブル(user_data)の指定したIDのデータ
*/
void deleteById(Long id);
}<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.ps.UserDataMapperPs">
<resultMap id="userDataResultMap" type="com.example.demo.mapper.UserData" >
<id column="id" property="id" jdbcType="BIGINT" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="birthY" property="birthY" jdbcType="VARCHAR" />
<result column="birthM" property="birthM" jdbcType="VARCHAR" />
<result column="birthD" property="birthD" jdbcType="VARCHAR" />
<result column="sex" property="sex" jdbcType="VARCHAR" />
<result column="memo" property="memo" jdbcType="VARCHAR" />
<result column="sex_value" property="sex_value" jdbcType="VARCHAR" />
</resultMap>
<select id="findAll" resultMap="userDataResultMap">
SELECT
id
, name
, birth_year as birthY
, birth_month as birthM
, birth_day as birthD
, sex
, memo
, CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE ''
END AS sex_value
FROM USER_DATA
</select>
<update id="truncateUserData">
TRUNCATE TABLE USER_DATA
</update>
<insert id="create" parameterType="com.example.demo.mapper.UserData">
INSERT INTO USER_DATA (
id
, name
, birth_year
, birth_month
, birth_day
, sex
, memo
) VALUES (
#{id}
, #{name}
, #{birthY}
, #{birthM}
, #{birthD}
, #{sex}
, #{memo,jdbcType=VARCHAR}
)
</insert>
<update id="update" parameterType="com.example.demo.mapper.UserData">
UPDATE USER_DATA SET name = #{name}, birth_year = #{birthY}
, birth_month = #{birthM}, birth_day = #{birthD}
, sex = #{sex}, memo = #{memo,jdbcType=VARCHAR}
WHERE id = #{id}
</update>
<delete id="deleteById" parameterType="java.lang.Long">
DELETE FROM USER_DATA WHERE id = #{id}
</delete>
</mapper>また、Mapperのテストクラスの内容は以下の通りで、DML(insert文, update文, delete文)実行後の結果を検証している。
package com.example.demo.mapper.ps;
import com.example.demo.mapper.DemoXlsDataSetLoader;
import com.example.demo.mapper.UserData;
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.TransactionDbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.github.springtestdbunit.annotation.DbUnitConfiguration;
import com.github.springtestdbunit.annotation.ExpectedDatabase;
import com.github.springtestdbunit.assertion.DatabaseAssertionMode;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import java.util.List;
// JUnit5ベースでMyBatisのテストを実行する
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class
, DirtiesContextTestExecutionListener.class
, TransactionDbUnitTestExecutionListener.class
, DbUnitTestExecutionListener.class})
@DbUnitConfiguration(dataSetLoader = DemoXlsDataSetLoader.class
, databaseConnection = {"dbUnitDatabaseConnectionPs"})
public class UserDataDmlTestPs {
/**
* ユーザーデータテーブル(user_data)へアクセスするマッパー
*/
@Autowired
private UserDataMapperPs userDataMapperPs;
/**
* 各テストメソッドを実行する前に行う処理を定義する.
*/
@BeforeEach
public void beforeTest() {
System.out.println();
System.out.println("*** UserDataDmlTestPsクラス テスト結果 start ***");
}
/**
* DML(insert,update,delete)文の実行結果を検証する.
*/
@Test
@DatabaseSetup("/com/example/demo/xls/databaseSetupTest.xlsx")
@ExpectedDatabase(value = "/com/example/demo/xls/expectedDatabaseTest.xlsx"
, assertionMode = DatabaseAssertionMode.NON_STRICT_UNORDERED)
public void userDataTest() {
// ユーザーデータ追加・更新・削除する前のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ DML実行前 ***");
List<UserData> userDataList = userDataMapperPs.findAll();
for (UserData userData : userDataList) {
System.out.println(userData);
}
System.out.println();
// ユーザーデータ(ID=4)を追加
UserData userData4 = new UserData(4, "テスト プリン4"
, 2016, 5, 6, "1", "テスト4", "");
userDataMapperPs.create(userData4);
// ユーザーデータ(ID=3)を更新
UserData userData3 = new UserData(3, "テスト プリン3更新後"
, 2015, 4, 21, "2", "テスト3更新後", "");
userDataMapperPs.update(userData3);
// ユーザーデータ(ID=2)を削除
userDataMapperPs.deleteById(2L);
// ユーザーデータ追加・更新・削除した後のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ DML実行後 ***");
userDataList = userDataMapperPs.findAll();
for (UserData userData : userDataList) {
System.out.println(userData);
}
}
/**
* 各テストメソッドを実行した後に行う処理を定義する.
*/
@AfterEach
public void afterTestClass() {
System.out.println("*** UserDataDmlTestPsクラス テスト結果 end ***");
System.out.println();
}
}上記テストクラスの実行結果は以下の通りで、DML(insert文, update文, delete文)実行でロールバックされていることが確認できる。
SQL Serverの場合のソースコードとテスト実行結果
テスト対象となるMapperの内容は、以下の通り。
package com.example.demo.mapper.ss;
import com.example.demo.mapper.UserData;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserDataMapperSs {
/**
* SQL Serverでユーザーデータテーブル(user_data)の全データを取得する
* @return ユーザーデータテーブル(user_data)の全データ
*/
List<UserData> findAll();
/**
* SQL Serverでユーザーデータテーブル(user_data)の全データを削除する
*/
void truncateUserData();
/**
* SQL Serverで指定したユーザーデータテーブル(user_data)のデータを追加する
* @param userData ユーザーデータテーブル(user_data)の追加データ
*/
void create(UserData userData);
/**
* SQL Serverで指定したユーザーデータテーブル(user_data)のデータを更新する
* @param userData ユーザーデータテーブル(user_data)の更新後データ
*/
void update(UserData userData);
/**
* SQL Serverで指定したIDをもつユーザーデータテーブル(user_data)のデータを削除する
* @param id ID
* @return ユーザーデータテーブル(user_data)の指定したIDのデータ
*/
void deleteById(Long id);
}<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.ss.UserDataMapperSs">
<resultMap id="userDataResultMap" type="com.example.demo.mapper.UserData" >
<id column="id" property="id" jdbcType="BIGINT" />
<result column="name" property="name" jdbcType="VARCHAR" />
<result column="birthY" property="birthY" jdbcType="VARCHAR" />
<result column="birthM" property="birthM" jdbcType="VARCHAR" />
<result column="birthD" property="birthD" jdbcType="VARCHAR" />
<result column="sex" property="sex" jdbcType="VARCHAR" />
<result column="memo" property="memo" jdbcType="VARCHAR" />
<result column="sex_value" property="sex_value" jdbcType="VARCHAR" />
</resultMap>
<select id="findAll" resultMap="userDataResultMap">
SELECT
id
, name
, birth_year as birthY
, birth_month as birthM
, birth_day as birthD
, sex
, memo
, CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE ''
END AS sex_value
FROM dbo.USER_DATA
</select>
<update id="truncateUserData">
TRUNCATE TABLE dbo.USER_DATA
</update>
<insert id="create" parameterType="com.example.demo.mapper.UserData">
INSERT INTO dbo.USER_DATA (
id
, name
, birth_year
, birth_month
, birth_day
, sex
, memo
) VALUES (
#{id}
, #{name}
, #{birthY}
, #{birthM}
, #{birthD}
, #{sex}
, #{memo,jdbcType=VARCHAR}
)
</insert>
<update id="update" parameterType="com.example.demo.mapper.UserData">
UPDATE dbo.USER_DATA SET name = #{name}, birth_year = #{birthY}
, birth_month = #{birthM}, birth_day = #{birthD}
, sex = #{sex}, memo = #{memo,jdbcType=VARCHAR}
WHERE id = #{id}
</update>
<delete id="deleteById" parameterType="java.lang.Long">
DELETE FROM dbo.USER_DATA WHERE id = #{id}
</delete>
</mapper>また、Mapperのテストクラスの内容は以下の通りで、DML(insert文, update文, delete文)実行後の結果を検証している。
package com.example.demo.mapper.ss;
import com.example.demo.mapper.DemoXlsDataSetLoader;
import com.example.demo.mapper.UserData;
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import com.github.springtestdbunit.TransactionDbUnitTestExecutionListener;
import com.github.springtestdbunit.annotation.DatabaseSetup;
import com.github.springtestdbunit.annotation.DbUnitConfiguration;
import com.github.springtestdbunit.annotation.ExpectedDatabase;
import com.github.springtestdbunit.assertion.DatabaseAssertionMode;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import java.util.List;
// JUnit5ベースでMyBatisのテストを実行する
@MybatisTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class
, DirtiesContextTestExecutionListener.class
, TransactionDbUnitTestExecutionListener.class
, DbUnitTestExecutionListener.class})
@DbUnitConfiguration(dataSetLoader = DemoXlsDataSetLoader.class
, databaseConnection = {"dbUnitDatabaseConnectionSs"})
public class UserDataDmlTestSs {
/**
* ユーザーデータテーブル(user_data)へアクセスするマッパー
*/
@Autowired
private UserDataMapperSs userDataMapperSs;
/**
* 各テストメソッドを実行する前に行う処理を定義する.
*/
@BeforeEach
public void beforeTest() {
System.out.println();
System.out.println("*** UserDataDmlTestSsクラス テスト結果 start ***");
}
/**
* DML(insert,update,delete)文の実行結果を検証する.
*/
@Test
@DatabaseSetup("/com/example/demo/xls/databaseSetupTest.xlsx")
@ExpectedDatabase(value = "/com/example/demo/xls/expectedDatabaseTest.xlsx"
, assertionMode = DatabaseAssertionMode.NON_STRICT_UNORDERED)
public void userDataTest() {
// ユーザーデータ追加・更新・削除する前のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ DML実行前 ***");
List<UserData> userDataList = userDataMapperSs.findAll();
for (UserData userData : userDataList) {
System.out.println(userData);
}
System.out.println();
// ユーザーデータ(ID=4)を追加
UserData userData4 = new UserData(4, "テスト プリン4"
, 2016, 5, 6, "1", "テスト4", "");
userDataMapperSs.create(userData4);
// ユーザーデータ(ID=3)を更新
UserData userData3 = new UserData(3, "テスト プリン3更新後"
, 2015, 4, 21, "2", "テスト3更新後", "");
userDataMapperSs.update(userData3);
// ユーザーデータ(ID=2)を削除
userDataMapperSs.deleteById(2L);
// ユーザーデータ追加・更新・削除した後のデータを確認
System.out.println("*** ユーザーデータテーブル(user_data)のデータ DML実行後 ***");
userDataList = userDataMapperSs.findAll();
for (UserData userData : userDataList) {
System.out.println(userData);
}
}
/**
* 各テストメソッドを実行した後に行う処理を定義する.
*/
@AfterEach
public void afterTestClass() {
System.out.println("*** UserDataDmlTestSsクラス テスト結果 end ***");
System.out.println();
}
}上記テストクラスの実行結果は以下の通りで、DML(insert文, update文, delete文)実行でロールバックされていることが確認できる。
要点まとめ
- JUnit5 DBUnitを利用して、DML(insert文, update文, delete文)を実行すると、どのDB上で実行した場合でも、テスト実行後にロールバックされる。



















