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の内容は、以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | <?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文)実行後の結果を検証している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 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の内容は、以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | <?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文)実行後の結果を検証している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 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の内容は、以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | <?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文)実行後の結果を検証している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 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の内容は、以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | <?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文)実行後の結果を検証している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 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上で実行した場合でも、テスト実行後にロールバックされる。