【MyBatis】Spring BootでMyBatisマッパを単体テストする

2023年11月18日

この記事の概要

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');