SpringでDBunitを使用するときのアノテーション

## はじめに
DBunitを実装する上でクラスに定義するアノテーションをなんとなくで使用していたので、改めてそれぞれが何を示しているのかまとめました。

```java
@ExtendWith(SpringExtension.class)
@SpringBootTest
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
    DirtiesContextTestExecutionListener.class, TransactionalTestExecutionListener.class,
    DbUnitTestExecutionListener.class}) // 1
@DbUnitConfiguration(dataSetLoader = XlsDataSetLoader.class) // 2
@DatabaseTearDown(type = DatabaseOperation.TRUNCATE_TABLE) // 3
class SampleTest {
```

## 1. リスナー設定
SpringでDBunitを使用するには、DbUnitTestExecutionListenerクラスを使用するようにテストを構成する必要があります。これを実現するのが@TestExecutionListenersアノテーションです。

### @TestExecutionListeners
クラスレベルに@TestExecutionListenersアノテーションを付けることで、テスト実行時に指定したTestExecutionListenerの処理を呼び出すことが可能になります。

@TestExecutionListenersアノテーションを明示的に指定しない場合、デフォルトで登録される TestExecutionListenerはOrderを持っており、呼び出し順は下記表の順に固定されています。 
※TestExecutionListenerが個別に指定された場合は、指定された順番通りに呼び出される

|No|TestExecutionListenerの実装クラス|説明|
|---|---|---|
|1|ServletTestExecutionListener|WebApplicationContextのテストをサポートするモックサーブレットAPIを設定する機能を提供している。|
|2|DirtiesContextBeforeModesTestExecutionListener|テストで使用するDIコンテナのライフサイクル管理機能を提供している。 テストクラスまたはテストメソッドの実行前に呼び出される。|
|3|DependencyInjectionTestExecutionLiLstener|テストで使用するインスタンスへのDI機能を提供している。|
|4|DirtiesContextTestExecutionListener|テストで使用するDIコンテナのライフサイクル管理機能を提供している。 テストクラスまたはテストメソッドの実行後に呼び出される。|
|5|TransactionalTestExecutionListener|テスト実行時のトランザクション管理機能を提供している。|
|6|SqlScriptsTestExecutionListener|@Sqlアノテーションで指定されているSQLを実行する機能を提供している。|

### 基本となるリスナー
DbUnitTestExecutionListenerを含めて以下4つのListenerが、DBUnitにおける基本の形となります。

```java
@TestExecutionListeners({
        DependencyInjectionTestExecutionListener.class,
        DirtiesContextTestExecutionListener.class,
        TransactionalTestExecutionListener.class,
        DbUnitTestExecutionListener.class})
```

|アノテーション名|役割|
|---|---|
|@￰DependencyInjectionTestExecutionListener|テスト実行時にSpringのDI機能を利用できるようにする。|
|@￰DirtiesContextTestExecutionListener|テストで使用するDIコンテナのライフサイクル管理機能を提供する。テストクラスまたはテストメソッドの実行後に呼び出される。|
|@￰TransactionalTestExecutionListener|テスト実行時のトランザクション管理機能を提供している。|
|@￰DbUnitTestExecutionListener|DBデータの設定・検証・後処理ができるようにする。@￰DatabaseSetup、@￰DatabaseTearDown、@￰ExpectedDatabaseをサポートする。|

## 2. データベース読み込み設定
Spring Test DBUnitにおいてテスト用データベースを設定する際に、@DbUnitConfigurationを使用します。
dataSetLoaderを設定せずアノテーションを使用した場合は、デフォルト設定となりXML形式のデータ定義ファイルが読み込まれます。以下例のようにdataSetLoaderを設定するとファイル形式を変更することは可能となります。
```java
// Excel形式のデータ定義ファイル読込み
@DbUnitConfiguration(dataSetLoader = XlsDataSetLoader.class)
```
ファイル形式を変更したい場合は、変更したい形式に対応したIDataSetインタフェースの実装クラスを生成する DataSetLoaderインタフェースの実装クラスを作成することで実現できます。

## 3. データベースのリセット
テストを完了したら@DatabaseTearDownアノテーションを使用することでデータベース、テーブルをリセットできます。アノテーションはメソッドまたはクラスレベルで適用可能です。

```java
@DatabaseTearDown(type = DatabaseOperation.TRUNCATE_TABLE)
```

DatabaseOperationクラスは、各テストの前後でデータベースに対する操作を実行することができ、以下のような操作を指定することが可能です。

|操作|説明|
|---|---|
|UPDATE|データセットのデータと主キーが一致しているデータを更新|
|INSERT|データセットの内容をデータベースに挿入|
|DELETE|データセットのデータと主キーが一致しているデータを削除|
|DELETE_ALL|データセットで指定したテーブルの全データを削除（ロールバック可能）|
|TRUNCATE|データセットで指定したテーブルの全データが削除（ロールバック不可能）|
|REFRESH|データセットのデータと主キーが一致しているデータが存在しない場合はインサートされ、存在する場合はデータセットの内容に更新|
|CLEAN_INSERT|DELETE_ALL操作に続いて INSERT操作を実行|
|NONE|何もしない|


## 参考文献
https://terasolunaorg.github.io/guideline/5.4.1.RELEASE/ja/UnitTest/ImplementsOfUnitTest/UsageOfLibraryForTest.html

https://terasolunaorg.github.io/guideline/5.4.1.RELEASE/ja/UnitTest/ImplementsOfUnitTest/PreparationForTest.html

https://springtestdbunit.github.io/spring-test-dbunit/

https://www.dbunit.org/components.html

https://spring.pleiades.io/spring-boot/docs/current/reference/html/features.html#features.testing

https://qiita.com/kaburankattara/items/ba738eae9905d51d2b88

https://qiita.com/Chayata/items/1ce99d2d908cacc57298