【MyBatis】Spring BootでMyBatisマッパを単体テストする
この記事の概要
Spring Boot + MyBatis + PostgreSQLのプロジェクトでMyBatisマッパの単体テストを作成する方法を紹介します。
この記事の内容は以下の環境で動作確認しています。
- Spring Boot 3.1.5
- Java 17
- PostgreSQL 15.4
- MyBatis-Generator-Core 1.4.2
- MyBatis-Spring-Boot-Starter 3.0.3
- mybatis-spring-boot-starter-test 3.0.3
Spring BootプロジェクトでMyBatisを使用する際にはmybatis-spring-boot-starter, mybatis-spring-boot-starter-testを利用するとSpring Boot プロジェクト中のbuild.gradleへ依存関係を追加するだけで簡単に設定が完了します。
参考情報
単体テストの構成
build.gradleに依存関係を追加します。
dependencies {
...
// MyBatis
implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.2'
// PostgreSQL
runtimeOnly 'org.postgresql:postgresql'
// MyBatisマッパのテスト用
testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.2'
}
単体テストは以下のように作成できます。マッパの作成方法やMyBatisの設定については【MyBatis Generator 1.4.2】Spring Boot3でMyBatis Dynamic SQLを使用するをご参照ください。
package com.example;
// importは省略
@MybatisTest // ①
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) // ②
@Sql("/sql/BookMapperTest.sql") //③
public class BookMapperTest {
// テスト対象のMyBatisマッパ
@Autowired
private BookMapper bookMapper;
@Test
public void select_by_primary_key_test() {
assertThat(bookMapper.selectByPrimaryKey(1).map(Book::getBookTitle).orElse("")).isEqualTo("test_book1");
}
@Test
public void select_test() {
assertThat(bookMapper.select(c -> c.where(bookTitle, isEqualTo("test_book1"))).stream().toList())
.extracting("bookTitle", "categoryId", "updatedAt")
.containsExactly(
tuple("test_book1", 1, OffsetDateTime.of(LocalDateTime.of(2023, 11, 11, 0, 0, 0), ZoneOffset.UTC))
);
}
@Test
public void count_test() {
var n = bookMapper.count(c -> c.where(categoryId, isEqualTo(2)));
assertThat(n).isEqualTo(2);
}
}
①がmybatis-spring-boot-starter-testで用意されているアノテーションです。MyBatisマッパの単体テストを作成するために使用します。mybatis-spring-boot-starter-test 2.0.1以降では@ExtendWith(SpringExtension.class)を省略可能です。@MybatisTestは@Transactionalを含んでいるので@Testを付与したテストごとにトランザクションが開始されます。
②が単体テストでPostgreSQLを使用するための設定です。デフォルトではインメモリDBを使用します。
③が単体テストで使用する初期データを投入するSQLです。必ずしも@SQLを使用する必要はありませんが、マッパのテストでマッパを使ってデータを投入するするのはテストの観点から避けました。BookMapperTest.sqlはresourcesディレクトリ内に以下のように作成しました。
insert into book
values
(1, 'test_book1', 1, '2022-05-01T12:00:00+09'),
(2, 'test_book2', 2, '2022-05-02T12:00:00+09'),
(3, 'test_book3', 2, '2022-05-03T12:00:00+09');