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

2025年8月23日

この記事の概要

Spring Boot + MyBatis + PostgreSQLのプロジェクトでMyBatisマッパの単体テストを作成する方法を紹介します。

この記事の内容は以下の環境で動作確認しています。

  • Spring Boot  3.4.7
  • Java 21
  • PostgreSQL 15.4
  • myBatis-spring-boot-starter 3.0.5
  • mybatis-spring-boot-starter-test 3.0.5

Spring BootプロジェクトでMyBatisを使用する際にはmybatis-spring-boot-starter, mybatis-spring-boot-starter-testを利用するとSpring Boot プロジェクト中のbuild.gradleへ依存関係を追加するだけで簡単に設定が完了します。

参考情報

テスト対象の処理概要

以下のようなカラムを持つBookテーブルからデータを検索する処理をMyBatisマッパーで作成します。MyBatisマッパーの単体テストを作ることが目的なので簡略したテーブル構成となっています。

カラム名概要
idINT主キーとなるID
nameVARCHAR(255)本の名称
category_idINT本が属するカテゴリーのID
updated_atTIMESTAMP WITH TIME ZONEデータ更新日時
Bookテーブル

上記のBookテーブルのDDLを以下のように作成しました。

CREATE TABLE book (
    id INT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    category_id INT NOT NULL,
    published_at TIMESTAMP WITH TIME ZONE NOT NULL
);

MyBatisマッパーの実装

Bookテーブルから主キーで検索するだけのシンプルなマッパーを作成します。

@Mapper
public interface BookMapper {
    Book findById(int bookId);
}

マッパーから実際に実行されるSQLは以下です。

<?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.domain.mapper.BookMapper">
    <select id="findById" resultType="com.example.demo.domain.model.Book">
        SELECT
            id,
            book_title,
            category_id,
            updated_at
        FROM book
        WHERE id = #{bookId}
    </select>
</mapper>

単体テストの構成

build.gradleに依存関係を追加します。

dependencies {
        ...
        // MyBatis
	implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.5'
        // PostgreSQL
	runtimeOnly 'org.postgresql:postgresql'
	// MyBatisマッパのテスト用
	testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.5'
}

単体テストは以下のように作成できます。MyBatis Generatorを使ったマッパの作成方法やMyBatisの設定については【MyBatis Generator 1.4.2】Spring Boot3でMyBatis Dynamic SQLを使用するをご参照ください。

package com.example;
// importは省略

@MybatisTest // ①
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) // ② 
@Sql("classpath:sql/BookMapper.sql") // ③
public class BookMapperTest {
    // CustomerMapperをインジェクション
    @Autowired
    private BookMapper bookMapper;

    @Test
    public void test1() {
        Book book = bookMapper.findById(1);
        assertThat(book.id()).isEqualTo(1);
        assertThat(book.name()).isEqualTo("test_book1");
        assertThat(book.categoryId()).isEqualTo(1);
        assertThat(book.updatedAt()).isEqualTo(OffsetDateTime.parse("2022-05-01T12:00:00+09:00"));
    }
}

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