Java の DBUnit を使ったテストを Testcontainers で実行してみる
はじめに
最近チームで Javaエンジニアのための ソフトウェアテスト実践入門 ~自動化と生成AIによるモダンなテスト技法~
を読んでいます。
その中で取り扱われていた DBUnit を以前学習した Testcontainers で動かしてみたいなと思ったのでやってみました。
目次
第1章 ソフトウェアテストの全体像
1.1 ソフトウェアテストの概要
1.1.1 ソフトウェアテストの基本的な考え方
テストの定義と本書のスコープ
「ソフトウェアテストの7原則」
ソフトウェアテストの目的と意義
ソフトウェアテストの限界
1.1.2 開発プロセスにおけるテストの位置付けと種類
ソフトウェア開発における2つのプロセス
ウォーターフォール開発における工程とV字モデル
1.1.3 テストケースの作成とテスト技法
テストケースの構成要素
ホワイトボックステストとブラックボックステスト
カバレッジ基準
同値分割法
境界値テスト
1.1.4 テスト技法の具体例
「特殊電卓」を題材にしたそれぞれのテスト技法
「特殊電卓」に対するホワイトボックステスト
「特殊電卓」に対するブラックボックステスト
「特殊電卓」に対する同値分割法
「特殊電卓」に対する境界値テスト
1.2 単体テストの手法と戦略
1.2.1 テストの分類と定義
テストを分類・定義する目的
単体テストと結合テストを分類する基準
単体テスト or 結合テスト?
1.2.2 単体テストの目的と要件
単体テストの目的
単体テストの要件
1.2.3 単体テストにおける基本的なプログラム構成と処理フロー
単体テストにおけるプログラム構成
テストケースの3つのフェーズ
テストの「成功」と「失敗」
テストケースの粒度
単体テストの独立性
前処理と後処理
1.2.4 テストダブルと「依存」
テストダブルとその分類
プログラムにおける「依存」とは
呼び出し先への「依存」の解決
単体テストにおける「依存性注入」
1.2.5 単体テストにおける検証パターン
出力値ベースの検証
状態ベースの検証
コミュニケーションベースの検証
1.2.6 単体テストの実行時間と自動化
単体テストの実行時間
迅速なフィードバック
単体テストによる保守性・拡張性の確保
単体テストの自動化とテストランナー
1.2.7 単体テストとブランチ戦略
Git Flow戦略の概要
単体テスト戦略とブランチ戦略の関係
1.2.8 単体テストの評価とアプローチ
単体テストにおける正確性の評価
単体テストにおけるテスト技法
1.2.9 テスト駆動開発
コラム "ロンドン学派"と"古典学派"
1.3 結合テストとシステムテスト
1.3.1 結合テスト
結合テストの分類と特徴
結合テストと他システム接続
結合テストの自動化
1.3.2 システムテスト
システムテストとは
E2Eテスト
テストピラミッド
1.3.3 パフォーマンステスト
パフォーマンステストとは
負荷テスト
ストレステスト
耐久テスト
1.4 テスティングフレームワーク
1.4.1 テスティングフレームワークの全体像
xUnitテスティングフレームワークとは
テスティングフレームワークのプログラム構成
1.5 CI/CD
1.5.1 CI/CDとテスト自動化
CI/CDとパイプライン
CI/CDツール
CI/CDパイプラインとテスト自動化
Git起点のCI/CDパイプライン
第2章 JUnit 5による単体テスト
2.1 JUnit 5のさまざまな機能
2.1.1 JUnit5の概要
JUnit4からJUnit5へ
JUnit5の主要な機能
2.1.2 JUnit5におけるプログラム構成
テストクラスとテスト対象クラスの関係性
テストクラスの作成と配置
テストメソッドの作成方法
テストメソッドの基本的な処理
テストクラスの実行
テストのスキップ
2.1.3 アサーションAPIとテストの成否
アサーションAPIの全体像
テストの成否
等価性の検証
真偽値の検証
null値かどうかの検証
インスタンスの型の検証
同一性の検証
コレクションや配列の検証
2.1.4 テストコードのドキュメンテーション
ドキュメンテーションとしての側面
テストクラスとテストメソッドのネーミング
@DisplayNameアノテーション
2.1.5 テストクラスのライフサイクルとテストフィクスチャ
ライフサイクルメソッド
テストフィクスチャ
2.1.6 テストクラスのグループ化と階層化
テストスイート
ネステッドクラス
2.1.7 パラメータ化テスト
パラメータ化テスト
パラメータ化テストの対象クラス
リテラル配列からのパラメータ取得
CSVファイルからのパラメータ取得
スタティックメソッドからのパラメータ取得
2.1.8 エラー発生有無のテスト
エラー発生時のテスト成否
fail()による明示的なテスト失敗
assertThrows()による例外のアサーション
2.1.9 その他の高度なテスト
タイムアウトのテスト
アサンプションAPI
2.2 単体テストにおける「依存性注入」とテストダブルの利用
2.2.1 「荷物配送サービス」の仕様とコード
「荷物配送サービス」の仕様とクラス構成
ShippingServiceクラスの仕様
CostCalculatorクラスの仕様
2.2.2 荷物配送サービスのテストコード
ShippingServiceを対象にしたテストクラス
2.2.3 テストダブルの利用
テストダブルの作成
「依存性注入」によるテストダブルへの置き換え
2.3 JUnitの開発環境
2.3.1 Gradleからのビルドテスト
Gradleとは
GradleとCI/CD
JUnit Platformの設定方法
ログ出力の設定方法
レポート出力の設定方法
ビルドテストにおけるグループ分け
2.3.2 JaCoCoによるカバレッジレポート
JaCoCoの設定
JaCoCoのレポート
第3章 モッキングフレームワークの活用
3.1 Mockitoによるモッキング
3.1.1 Mockitoの基本
Mockitoの概要
テストダブルとモック
Mockitoによるモッキング手順
Mockitoの主要なAPI
3.1.2 モックの作成と振る舞いの設定
モックの作成
疑似的な振る舞いを設定するための2つの方式
when-then方式
do-when方式
スタティックメソッドのモック化
3.1.3 引数マッチングと動的な振る舞い
引数マッチングAPIとは
引数マッチングの挙動
argThat()による汎用的なマッチング条件指定
Answerによる動的な振る舞い設定
3.1.4 コミュニケーションベース検証
コミュニケーションベース検証の基本
順番を意識したコミュニケーションベース検証
3.1.5 スパイの作成と振る舞いの設定
スパイとは
スパイの作成
振る舞いの設定とスパイの挙動
副作用の発生抑止と検証
3.1.6 JUnitテストコードにおけるMockitoの活用事例
サービスとテストの全体像
Mockito導入前
Mockito導入後の変更点
第4章 データベーステストの効率化
4.1 DBUnitによるデータベーステスト
4.1.1 DBUnitの基本
DBUnitの概要と主要な機能
DBUnitリソースの単位と配置
DBUnitのテストフィクスチャ
テスト対象のDAO
4.1.2 DBUnitテストフィクスチャとデータの初期化
DBUnitテストフィクスチャのセットアップ
初期データのセットアップ
4.1.3 CRUD操作のテスト
読み込み系操作(検索)のテスト
書き込み系操作(挿入/削除/更新)のテスト
4.1.4 DBUnitの活用事例
サービスとテストの全体像
第5章 Spring Bootアプリケーションの単体テスト
5.1 Spring Boot Testによる単体テスト
5.1.1 Spring BootとSpring Boot Test
Spring Bootとは
Spring BootによるWebアプリケーションのシステム構成
Spring Boot Testの概要と主要な機能
Spring Boot Testが提供するアノテーション
5.1.2 サービスの単体テスト
サービスの単体テスト概要
サービス単体テストの具体例
5.1.3 MockMVCによるコントローラの単体テスト
MockMVCの概要と主要な機能
MockMVCによるテストクラスの構造
疑似的なリクエストの構築
レスポンス検証項目の設定
5.1.4 MockMVCによるテストクラス実装の具体例
テスト対象アプリケーションのページ遷移
テスト対象コントローラクラス
MockMVCを利用したテストクラス
5.1.5 テスト用プロファイルとプロパティ
テスト用プロファイルの切り替え
テスト用プロパティの設定
第6章 REST APIのテスト
6.1 RestAssuredによるREST APIのテスト
6.1.1 RestAssuredの基本
REST APIのテスト概要
RestAssuredの概要と主要なAPI
テスト対象RESTサービスのURL設定(全体)
6.1.2 RestAssuredとGiven-When-Thenパターン
Given-When-Thenパターン
リクエストの設定(Given)
テスト対象RESTサービスへのリクエスト送信(When)
レスポンスの検証と抽出(Then)
6.1.3 RestAssuredによるテストクラス実装の具体例
GETメソッドによる主キー検索APIのテスト
GETメソッドによる条件検索APIのテスト
POSTメソッドによる新規作成APIのテスト
PUTメソッドによる置換APIのテスト
DELETEメソッドによる削除APIのテスト
6.2 WireMockによるモックサーバー構築
6.2.1 WireMockによるHTTPサーバーのモッキング
WireMockの基本的なクラス構成
WireMockの主要なAPI
6.2.2 WireMockによるモックサーバー構築の具体例
具体例1:リクエストボディを持つREST API
具体例2:Person(人物)を操作するためのREST API
具体例3:静的ファイルを返すREST API
第7章 UIテストの自動化
7.1 SelenideによるWebブラウザのUIテスト
7.1.1 Seleniumの概要
SeleniumとWebDriverの仕組み
SeleniumによるUI操作
7.1.2 Selenideの基本
Selenideの主要なAPI
Webブラウザを操作するためのAPI
Webページ情報取得のためのAPI
UI要素を取得するためのAPI
UIを操作するためのAPI
UI要素を検証するためのAPI
スクリーンショット取得のためのAPI
その他のAPI
7.1.3 Selenideによるテストクラス実装の具体例
「テックブックストア」
第8章 負荷テストの自動化
8.1.1 Gatlingの基本
負荷テストの概要と負荷テストツールの機能
Gatlingの概要
シミュレーションとシナリオ
シミュレーションクラスの基本的なクラス構成
8.1.2 シミュレーションクラスの作成方法
Gatlingの主要なAPI
HTTP共通情報設定API
フィーダー設定API
シナリオ構築API
アクション構築API
レスポンス検証API
シミュレーション設定API
8.1.3 シミュレーションの実行方法と結果レポート
「テックブックストア」の負荷テスト
負荷テストの実行
負荷テストの結果レポート
Appendix
A.1 GitHub Actionsとコンテナを活用したCI/CD
A.1.1 コンテナとCI/CDパイプライン
コンテナとDocker
コンテナイメージとコンテナレジストリ
コンテナ管理プラットフォームKubernetes
CI/CDツール+コンテナ環境の組み合わせ
A.1.2 GitHub Actions+Amazon EKSによるパイプライン構築例
GitHub ActionsとGHCR
GitHub Actionsにおけるアクション
ワークフローの全体像
ワークフローファイルの概要
ジョブにおける各ステップの処理
A.2 生成AIのテストへの活用
A.2.1 本書で取り上げる生成AI
生成AIをテストに活用するためのアプローチ
A.2.2 JUnit単体テストでの活用
テスト仕様からテストコード生成(アプローチ①)
プロダクションコードからテストコード生成(アプローチ②)
A.2.3 REST APIテストでの活用
RestAssuredによるテストコード生成
WireMockによるモックサーバーのコード生成
A.2.4 SelenideによるUIテストでの活用
A.2.5 Gatlingによる負荷テストでの活用
書籍のリポジトリ
書評
一旦本の書評をしておきます。
そもそも自分は Java のテストについて詳しくなかったので本書を手にとりました。
内容としては、テストの基礎理論を学びたい人から、実際にテストツールを活用したい人まで、幅広いニーズに応える参考書だと思いました。特に、現場での実践を見据えた構成と最新技術への対応が際立ちました。ソフトウェアテストに興味がある方や現場でテストを強化したい方に、ぜひ一読をお勧めします。
全体像の明確さ
第1章では、ソフトウェアテストの基本的な考え方から具体的なテスト技法までを体系的に解説し、初心者でも理解しやすい構成となっています。
実践的アプローチ
各章でJUnitやMockito、RestAssuredといった具体的なツールの活用方法を取り上げ、読者がすぐに実践できるような具体例が豊富に掲載されています。
最新技術への対応
Appendix ではありますが、、生成AIを活用したテスト自動化やGitHub Actionsを用いたCI/CDパイプラインの構築例など、最新の技術トレンドにも対応しており、実務での応用力を高める内容です。
幅広いトピック
単体テスト、結合テスト、UIテスト、負荷テストなど多岐にわたるテスト手法を扱い、ソフトウェアテストの全領域をカバーしています。
では書籍にあった DBUnit を TestContainers の mysql で動かしてみようとおもいます。
DBUnit を TestContainer で実行する
DBUnitは、Javaアプリケーションのテストでデータベースの初期化や検証を簡単に行えるライブラリです。テストごとにデータベースの状態をリセットし、期待値と実際のデータを比較する機能を提供するため、再現性の高いテストが可能になります。XMLやCSV形式で初期データや期待値を定義でき、特にDAOやリポジトリのテストで有用です。
最初に実際に作成したリポジトリはこちらです。
細かなところはこちらをご覧ください。
ベースにしたプログラムは以下の部分です。
第4章 データベーステストの効率化
4.1.3 CRUD操作のテスト
読み込み系操作(検索)のテスト
書き込み系操作(挿入/削除/更新)のテスト
上記リポジトリの src/test/java/org/example/company/EmployeeDAOTest.java
を Testcontainers 対応にしてみました。
Gradle から Maven に変更
もともと Gradle で書かれていましたが、Maven を使うことが多いので以前の記事を参考に書き換えてみました。
<?xml version="1.0" encoding="UTF-8"?>
<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>org.example</groupId>
<artifactId>DaoTestSample</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mysql</artifactId>
<version>1.20.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.dbunit/dbunit -->
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>2.8.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
</plugin>
</plugins>
</build>
</project>
EmployeeDAOTest.java を Testcontainers 対応にする
対応後の EmployeeDAOTest.java です。
基本的にセットアップ関連のところしか変更していません。
package org.example.company;
import org.dbunit.IDatabaseTester;
import org.dbunit.JdbcDatabaseTester;
import org.dbunit.database.DatabaseConfig;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.csv.CsvDataSet;
import org.dbunit.ext.mysql.MySqlDataTypeFactory;
import org.dbunit.operation.DatabaseOperation;
import org.junit.jupiter.api.*;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.utility.DockerImageName;
import java.io.File;
import java.time.LocalDate;
import java.util.Collections;
import java.util.List;
import static org.dbunit.Assertion.assertEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertIterableEquals;
@DisplayName("EmployeeDAOを対象にしたテストクラス")
public class EmployeeDAOTest {
// 初期スキーマを格納するディレクトリ
private static final String SCHEMA_DIR = "SCHEMA";
// DBUnitのリソースを格納するディレクトリ
private static final String INIT_DATA_DIR = "src/test/resources/INIT_DATA";
private static final String EXPECTED_DATA_DIR_1 = "src/test/resources/EXPECTED_DATA_1";
private static final String EXPECTED_DATA_DIR_2 = "src/test/resources/EXPECTED_DATA_2";
private static final String EXPECTED_DATA_DIR_3 = "src/test/resources/EXPECTED_DATA_3";
static MySQLContainer<?> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"))
.withInitScripts(
SCHEMA_DIR + "/1_COMPANY_DROP.sql",
SCHEMA_DIR + "/2_COMPANY_DDL.sql",
SCHEMA_DIR + "/3_COMPANY_DML.sql"
); // ①
// テスト対象クラス
EmployeeDAO employeeDAO;
// DBUnitのためのテストフィクスチャ
IDatabaseTester databaseTester;
IDatabaseConnection databaseConnection;
// ②
@BeforeAll
static void beforeAll() {
mysql.start();
}
@AfterAll
static void afterAll() {
mysql.stop();
}
/*
* テスト毎の DBUnit のテストフィクスチャやデータベース上のデータを初期化する
*/
@BeforeEach
void setUpDatabase() throws Exception {
// ③
String driver = mysql.getDriverClassName();
String url = mysql.getJdbcUrl();
String user = mysql.getUsername();
String password = mysql.getPassword();
// IDatabaseTesterを初期化する
databaseTester = new JdbcDatabaseTester(driver, url, user, password);
// IDatabaseConnectionを取得する
databaseConnection = databaseTester.getConnection();
// MySQL用のDataTypeFactoryを設定する
DatabaseConfig config = databaseConnection.getConfig();
config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new MySqlDataTypeFactory());
// IDatabaseConnectionからJDBCコネクションを取り出し、EmployeeDAOを初期化する
employeeDAO = new EmployeeDAO(databaseConnection.getConnection());
// 初期データをセットアップする
initData();
}
/*
* 初期データをセットアップする
*/
private void initData() throws Exception {
// CSVファイルから初期データを読み込む
IDataSet dataSet = new CsvDataSet(new File(INIT_DATA_DIR));
// データベースの対象テーブルから全件削除し、読み込んだ初期データを挿入する
databaseTester.setDataSet(dataSet);
databaseTester.setSetUpOperation(DatabaseOperation.CLEAN_INSERT);
databaseTester.onSetup();
}
@Test
@DisplayName("主キー検索の結果をテストする")
void test_SelectEmployee() {
// テストを実行し、実測値を取得する
Employee actual = employeeDAO.selectEmployee(10001);
// 期待値を生成する
Employee expected = new Employee(10001, "Alice", "SALES" ,LocalDate.of(2015, 4, 1),
"MANAGER", 500000);
// 期待値と実測値が一致しているかを検証する
assertEquals(expected, actual);
}
@Test
@DisplayName("条件検索の結果をテストする")
void test_SelectEmployeesBySalary() throws Exception {
// テストを実行し、実測値リストを取得する
List<Employee> actualList = employeeDAO.selectEmployeesBySalary(300000, 400000);
// 期待値リストのサイズと実測値リストのサイズが一致しているかを検証する
assertEquals(3, actualList.size());
// 期待値リストを生成する
List<Employee> expectedList = List.of(
new Employee(10003, "Carol", "HR" ,LocalDate.of(2015, 4, 1), "CHIEF", 350000),
new Employee(10004, "Dave", "SALES" ,LocalDate.of(2015, 4, 1), "LEADER", 400000),
new Employee(10005, "Ellen", "SALES" ,LocalDate.of(2017, 4, 1), "CHIEF", 300000));
// 実測値リストをソートする
Collections.sort(actualList, (e1, e2) -> {
if (e1.getEmployeeId() < e2.getEmployeeId()) return -1;
if (e1.getEmployeeId() > e2.getEmployeeId()) return 1;
return 0;
});
// 期待値リストと実測値リストが一致しているかを検証する
assertIterableEquals(expectedList, actualList);
}
@Test
@DisplayName("挿入の結果をテストする")
void test_InsertEmployee() throws Exception {
// テストを実行する
Employee employee = new Employee(10006, "Frank", "SALES", LocalDate.of(2019, 10, 1),
null, 380000);
employeeDAO.insertEmployee(employee);
// DBUnitのAPIで、期待値テーブルをCSVファイルから取得する
IDataSet expectedDataSet = new CsvDataSet(new File(EXPECTED_DATA_DIR_1));
ITable expectedTable = expectedDataSet.getTable("EMPLOYEE");
// DBUnitのAPIで、実測値テーブルをデータベースから取得する
IDataSet databaseDataSet = databaseConnection.createDataSet();
ITable actualTable = databaseDataSet.getTable("EMPLOYEE");
// DBUnitのAPIで、期待値テーブルと実測値テーブルが一致しているかを検証する
assertEquals(expectedTable, actualTable);
}
@Test
@DisplayName("削除の結果をテストする")
void test_DeleteEmployee() throws Exception {
// テストを実行する
employeeDAO.deleteEmployee(10004);
// DBUnitのAPIで、期待値テーブルをCSVファイルから取得する
IDataSet expectedDataSet = new CsvDataSet(new File(EXPECTED_DATA_DIR_2));
ITable expectedTable = expectedDataSet.getTable("EMPLOYEE");
// DBUnitのAPIで、実測値テーブルをデータベースから取得する
IDataSet databaseDataSet = databaseConnection.createDataSet();
ITable actualTable = databaseDataSet.getTable("EMPLOYEE");
// DBUnitのAPIで、期待値テーブルと実測値テーブルが一致しているかを検証する
assertEquals(expectedTable, actualTable);
}
@Test
@DisplayName("一括更新の結果をテストする")
void test_UpdateSalary() throws Exception {
// テストを実行する
employeeDAO.updateEmployeeSalary("SALES", 3000);
// DBUnitのAPIで、期待値テーブルをCSVファイルから取得する
IDataSet expectedDataSet = new CsvDataSet(new File(EXPECTED_DATA_DIR_3));
ITable expectedTable = expectedDataSet.getTable("EMPLOYEE");
// DBUnitのAPIで、実測値テーブルをデータベースから取得する
IDataSet databaseDataSet = databaseConnection.createDataSet();
ITable actualTable = databaseDataSet.getTable("EMPLOYEE");
// DBUnitのAPIで、期待値テーブルと実測値テーブルが一致しているかを検証する
assertEquals(expectedTable, actualTable);
}
}
主に変更した箇所を説明していきます。
変更箇所①
static MySQLContainer<?> mysql = new MySQLContainer<>(DockerImageName.parse("mysql:8.0"))
.withInitScripts(
SCHEMA_DIR + "/1_COMPANY_DROP.sql",
SCHEMA_DIR + "/2_COMPANY_DDL.sql",
SCHEMA_DIR + "/3_COMPANY_DML.sql"
);
MySQLコンテナを初期化し、MySQL 8.0を使用します。
起動時に指定された初期化スクリプト(DROP、DDL、DML)を実行してデータベースを設定。
この設定により、テスト環境でのMySQLデータベースが確立され、テストで利用可能になります。
変更箇所②
@BeforeAll
static void beforeAll() {
mysql.start();
}
@AfterAll
static void afterAll() {
mysql.stop();
}
Testcontainers 用に新しく追加しています。
@BeforeAll:
mysql.start()でTestcontainersのMySQLコンテナを起動します。
@AfterAll:
mysql.stop()でMySQLコンテナを停止・クリーンアップします。
変更箇所③
@BeforeEach
void setUpDatabase() throws Exception {
String driver = mysql.getDriverClassName();
String url = mysql.getJdbcUrl();
String user = mysql.getUsername();
String password = mysql.getPassword();
// IDatabaseTesterを初期化する
databaseTester = new JdbcDatabaseTester(driver, url, user, password);
// IDatabaseConnectionを取得する
databaseConnection = databaseTester.getConnection();
// MySQL用のDataTypeFactoryを設定する
DatabaseConfig config = databaseConnection.getConfig();
config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY, new MySqlDataTypeFactory());
// IDatabaseConnectionからJDBCコネクションを取り出し、EmployeeDAOを初期化する
employeeDAO = new EmployeeDAO(databaseConnection.getConnection());
// 初期データをセットアップする
initData();
}
Testcontainersからの接続情報の取得:
MySQLコンテナからJDBC接続に必要な情報(ドライバ、URL、ユーザー名、パスワード)を取得するように変更しています。それ以外に変更はありません。
テスト実行結果
まとめ
Java の DBUnit を使ったテストを Testcontainers で実行してみました。
Testcontainers と DBUnit を使うことでコンテナ環境で DB に接続したテストを簡単に行えるようになるのでお勧めです😃
Discussion