Spring BootのテストでJUnit5+H2+@DataJpaTestアノテーションでテストする方法

Spring BootのテストでJUnit5+H2+@DataJpaTestアノテーションでテストする方法

リポジトリインタフェースのテストでDBSetup,DBUnitあたりを使うことが多いと思うのですが、H2 + @DataJpaTestアノテーションを使うことによってデーたベースをインメモリにすることができます。

H2 + @DataJpaTestアノテーションのメリットは以下の通りです。

ライブラリ メリット デメリット
DBSetup 超流行っている 各開発者のテストデータによって他の開発者のテストケースが失敗する恐れがある
H2 インメモリデータベースなので閉じられたデータベースでのテストとなる ネイティブクエリを使用している場合、H2と構文が異なる場合、使えない恐れがある

build.gradleのdependenciesです。

dependencies {
// 省略
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.2.0'
testImplementation 'org.assertj:assertj-core:3.15.0' // for assertion
testImplementation 'com.h2database:h2:1.4.200' // for in memory database
}

view raw
gistfile1.txt
hosted with ❤ by GitHub

リポジトリクラスのテストコードサンプルです。

package jp.co.confrage.repository;
import java.util.List;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import com.example.demo.primary.entity.EmpUser;
@DataJpaTest
public class EmpUserRepositoryTest {
@Autowired private TestEntityManager em;
@Autowired private EmpUserRepository repository;
@BeforeEach
void beforeEach() { // ここでエンティティクラスを使用してH2にデータ作成する
em.persist(new EmpUser("STOF", 20));
em.persist(new EmpUser("ETHOSENS", 30));
em.persist(new EmpUser("dulcamara", 40));
}
@Test
public void サンプルテスト() {
List list = repository.findByHogehoge();
Assertions.assertThat(list.size()).isEqualTo(3);
}
}

view raw
gistfile1.txt
hosted with ❤ by GitHub

@DataJpaTestアノテーション

テストクラスに対して@DataJpaTestアノテーションをつけます。

これで、インメモリDBの設定をしたり@Entity,@Repositoryアノテーションが付加されたクラスやインタフェースをBean登録されます。

@ExtendWith(SpringExtension.class)アノテーションは、@DataJpaTestアノテーションに含まれているため不要です。

インメモリデータベースを使用することにより、各テストの前処理でtruncateなどの処理が不要になりますのでDBSetupよりも便利だと思います。

JUnitテスト時のコンソールログにH2に接続されているログが出力されていることが確認できます。

参考サイト

https://howtodoinjava.com/spring-boot2/testing/datajpatest-annotation/

PKがサロゲートキーの場合(PostgreSQL)

PKがサロゲートキーでシーケンスオブジェクトで採番している場合、テストのたびにシーケンスオブジェクトを初期化しないと、各テスト間でシーケンスを保持してしまうことになり、独立性が保てなくなります。

PostgreSQLの場合とH2ではシーケンスオブジェクトの初期化が違います。テストの@BeforeEachアノテーションを付与しているメソッドでTestEntityManagerからH2のネイティブクエリを発行する必要があります。

@Autowired private TestEntityManager em;
@BeforeEach
void beforeEach() {
em.getEntityManager()
.createNativeQuery("alter sequence mst_id_seq restart with 1 ") // シーケンスオブジェクト名:mst_id_seq
.executeUpdate(); // シーケンスオブジェクトの採番を初期化
em.clear(); // 管理状態をクリア
}

view raw
HogeTest.java
hosted with ❤ by GitHub

スポンサーリンク
  • このエントリーをはてなブックマークに追加
  • Evernoteに保存Evernoteに保存
スポンサーリンク

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA