SpringBootを用いたWebアプリ開発で結合テスト(以下IntegrationTest)を実施する際に、データベース周りの設定がリポジトリテスト(以下RepositoryTest)と異なり、改めてテストの設定について学習した内容を以下に記載する。
前提条件
環境
IDE | 言語 | APPフレームワーク | テストフレームワーク | SQL制御 | SQL |
---|---|---|---|---|---|
IntelliJ IDEA 2024.1.4 | java 21.0.4 | Spring Boot 3.3.3 | JUnit 5 | MyBatis 3.0.3 | MySQL 8.0.39 |
Mainでの設定
※本題とはあまり関係ないので、RepositoryTestでの設定から読んでいただくことをおススメします。
SpringBootでのSQL制御のライブラリやフレームワークにはMyBatis、Spring Data JPA、JDBC (JdbcTemplate)、Spring Data JDBCなどがあるが、今回はMyBatisを用いた場合の例であることを承知されたい。
MyBatis
MyBatisによるSQL制御の特徴は以下の通り。
- 比較的軽量で高パフォーマンス
- SQLの知識が必要
SQLの知識が必要な点は、長所にも短所にもなり得る。SQL習得者にとっては複雑なクエリを記述できること、またコードの可読性が高くなることを意味する。一方、SQL未習得者にとってはSQLの学習コストを受け入れる必要がある(個人的にはSQLくらい勉強すべき)。
使用するためには、build.gradleで以下を設定する。
dependencies {
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3'
}
その他の設定
MySQL Connector
MySQL 8.0 リファレンスマニュアルによると、JavaアプリケーションでMySQLを使用するにはMySQL Connector/Jが必要となる。
Connector/J は標準 JDBC (Java Database Connectivity) API を使用して、Java アプリケーションから、MySQL に接続するためのドライバサポートを提供します。
dependencies {
runtimeOnly 'com.mysql:mysql-connector-j'
}
SQLへの接続設定
Connector/JでJDBCを使用して指定のデータベースにアクセスする設定を追加。
spring.datasource.url=jdbc:mysql://localhost:3306/database_name
spring.datasource.username=username
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
オブジェクトマッピング
一般的にSQLではスネークケースで命名するのに対して、Javaではキャメルケースで命名するため、両者をapplication.propertiesでマッピングする必要がある。
mybatis.configuration.map-underscore-to-camel-case=true
@Mapper
@Mapper
をインターフェースに付けると、そのインターフェースがSQL操作を行うクラス(マッパークラス)としてMyBatisによって認識される。
@Mapper
public interface Repository {
--- 各種メソッドを記載 ---
}
RepositoryTestでの設定
@MybatisTest
@MybatisTest
を使用したクラスでは以下の3つの特徴がある。
-
テスト環境自動構築:
@Mapper
インターフェースを使用したデータベース関連のテストに特化しており、必要なコンポーネントのみをテスト用に起動する - テスト用データベース設定:H2などのテスト用データベースを使用するように自動的に設定される
-
@Transactional
サポート:デフォルトで@Transactional
が付与され、各テストメソッドの後にトランザクションが自動的にロールバックされる
dependencies {
testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.3'
}
@MybatisTest
class FootballRepositoryTest {
--- 各種メソッドを記載 ---
}
H2DB
前述の通り、@MybatisTest
を付加したクラスではインメモリデータベースを使用するため、そのセットアップが必要。以下はインストールおよび接続設定のみで、schema.sqlとdata.sqlによる初期データセットアップが別途必要。
dependencies {
testImplementation 'com.h2database:h2:2.3.232'test:3.0.3'
}
接続設定は、mainとは別にtest/resourcesにapplication.propertiesの作成が必要。
spring.datasource.url=jdbc:h2:~/test;MODE=MySQL
spring.datasource.username=sa
spring.datasource.password=sa
spring.datasource.driver-class-name=org.h2.Driver
spring.h2.console.enabled=true
IntegrationTestでの設定
基本設定として、@SpringBootTest
と@AutoConfigureMockMvc
を使用する前提で話を進める。また、データベースはRepositoryTestと同様H2DBを使用する。
@SpringBootTest
@AutoConfigureMockMvc
class FootballIntegrationTest {
--- 各種メソッドを記載 ---
}
前述の通り、@MybatisTest
ではデータベース周りの設定を自動で設定してくれる部分が大きかった。ここで@MybatisTest
の特徴を再掲する。
@MybatisTest
を使用したクラスでは以下の3つの特徴がある。
- テスト環境自動構築
- テスト用データベース設定
@Transactional
サポート
テスト環境自動構築については、IntegrationTestと関係がないのでここでは触れない。
残りの2点について、IntegrationTestではマニュアルでの設定が必要なので、以下に説明する。
テスト用データベース設定
データベースに関する設定をせずにテストを実施するとエラーが発生する(詳細は不明、@SpringBootTest
のデフォルトデータベースの問題と思うが誰か教えてください。)
結論から言うと、@AutoConfigureTestDatabase
によって、用いるデータベースを明示する必要がある。
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureTestDatabase(replace = Replace.ANY) // 'AUTO_CONFIGURED'も可
class FootballIntegrationTest {
--- 各種メソッドを記載 ---
}
Replace
のオプションは以下の通り。
-
ANY
:自動構成されたか手動で定義されたかにかかわらず、DataSource Bean を交換 -
AUTO_CONFIGURED
:自動構成されている場合にのみ、DataSource を交換 -
NONE
:アプリケーションのデフォルト DataSource を置き換えない
今回のケースではANY
とAUTO_CONFIGURED
で成功するので、デフォルトはNONE
で設定されていると推定される。
@Transactional
設定
こちらも@MybatisTest
と異なり、自動で設定してくれないので、手動で付加する必要がある。
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureTestDatabase(replace = Replace.ANY) // 'AUTO_CONFIGURED'も可
@Transactional
class FootballIntegrationTest {
--- 各種メソッドを記載 ---
}
あとがき
今回の記事は結合テスト時の設定とその根拠の覚書のような形でまとまった。
テストの設定には他にも気になる部分が多いので、続けて投稿する予定。