LoginSignup
1
0

DBUnitを導入する(Spring Boot,Maven)

Last updated at Posted at 2024-02-05

DBUnitとは、データベースに依存するクラスのテストを行うためのJUnit拡張フレームワークです。

メリットとしては、データベースアクセスを伴うプロダクトコードの単体テストを行うときに、条件となるテーブルのレコード状態をテストコードによってつくることができるため、テストの再現性が高くなります。

依存関係

pom.xmlに以下の依存関係を追加します。

		<!-- https://mvnrepository.com/artifact/org.dbunit/dbunit -->
		<dependency>
			<groupId>org.dbunit</groupId>
			<artifactId>dbunit</artifactId>
			<version>2.7.3</version>
			<scope>test</scope>
		</dependency>

また、今回は、インプットファイルとしてExcelファイル(.xls、.xlsx)を使用します。
そのため、Apache poiも必要になります。

  	<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
  	<dependency>
  		<groupId>org.apache.poi</groupId>
  		<artifactId>poi</artifactId>
  		<version>5.2.5</version>
  		<scope>test</scope>
  	</dependency>

  	<dependency>
  		<groupId>org.apache.poi</groupId>
  		<artifactId>poi-ooxml</artifactId>
  		<version>5.2.2</version>
  		<scope>test</scope>
  	</dependency>

Excelファイルの定義

テーブルに対する入力となるExcelファイルを作成します。

以下スクショのように記述します。
(A5-mk2からレコードをコピーして貼り付けると非常に楽です。)

image.png

Excelファイルは、src/test/resources配下に置きましょう。

ポイントとしては、
・ヘッダ行が必要です。

・nullにしたい場合は、セルを空にします。

・シート名は、テーブルの物理名にします。

・シートは複数可能です。ここがcsvファイルとの違いで、何テーブルでも処理することができます。
なお、外部キー制約のあるテーブルを更新対象にする場合は、親テーブルを左のシート、子テーブルを右のシートにしましょう。逆順だと、実行時にSQLExceptionになります。

テストクラス

・DatabaseConnectionコンストラクタの第2引数には、スキーマ名を指定します。

・execute(iconn, dataSet)メソッドが、実際にテーブルレコードを書き換える処理になります。
下の例では、DatabaseOperation.CLEAN_INSERTとしており、まずテーブルレコードを全削除した上で、Excelに記載されたデータを投入する挙動になります。

import static org.junit.jupiter.api.Assertions.fail;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;

import javax.sql.DataSource;

import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.excel.XlsDataSet;
import org.dbunit.operation.DatabaseOperation;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class ApplicationTests {

	@Autowired
	DataSource dataSource;

	public void cleanAndInsertTables(){
		try (Connection conn = dataSource.getConnection()){
			IDatabaseConnection iconn = new DatabaseConnection(conn, "public");
			Path xlsxFile = Paths.get(
				"src\\test\\resources\\table_data.xlsx");			
			IDataSet dataSet = new XlsDataSet(xlsxFile.toFile());
			DatabaseOperation.CLEAN_INSERT.execute(iconn, dataSet);
		}catch(Exception e){
			e.printStackTrace();
			fail();
		}
	}

	@Test
	public void testCase1(){
		cleanAndInsertTables();
		// do something
	}
}

テストコードを実行すると、テーブルにはExcelで記述した7レコードのみが入った状態をつくることができます。

DatabaseOperationについて

DatabaseOperationには、以下の種類が用意されています(すべての挙動までは把握、確認していません)。

NONE
UPDATE
INSERT
REFRESH
DELETE
DELETE_ALL
TRUNCATE_TABLE
CLEAN_INSERT
TRANSACTION
CLOSE_CONNECTION

DELETEは、Excelに記載したレコードデータのみ削除します。
DELETE_ALLは、すべてのレコードを削除します。ただしTRUNCATE_TABLEの方が高速なので、基本的にこちらを使う方が良さそう。
(なお余談ですが、PostgreSQLではtruncateしてもシーケンスはリセットされません。MySQLではリセットされます)

最もよく使うのはCLEAN_INSERTでしょう。DELETE_ALLした後にINSERTする挙動になります。

補足

テストクラスで、データベースの接続情報として、

@Autowired
DataSource dataSource;

としていますが、これはapplication.propertiesに下記が定義されていれば、自動的にDIされるので、Configurationで定義する必要はありません。

spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://アドレス:ポート/データベース名
spring.datasource.username=ユーザ名
spring.datasource.password=パスワード

下記のような記述は不要↓↓↓

import javax.sql.DataSource;

import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;

@Configuration
public class DatasourceConfig {

  @Bean
  public DataSource dataSource() {
      return new TransactionAwareDataSourceProxy(
              DataSourceBuilder
                      .create()
                      .username("secret")
                      .password("secret")
                      .url("jdbc:postgresql://localhost:5432/sampledb")
                      .driverClassName("org.postgresql.Driver")
                      .build());
  }
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0