単体テストを簡単に Unitils 〜データベーステスティング 2 〜

前回の

blog1.mammb.com

からの続きです。

テストケースの作成

Unitilsでデータベーステストを行う場合には、JUnit4の場合は以下のようにRunWithアノテーションにて UnitilsJUnit4TestClassRunner を指定します。

import org.junit.runner.RunWith;
import org.unitils.UnitilsJUnit4TestClassRunner;

@RunWith(UnitilsJUnit4TestClassRunner.class)
public class MyTest {
}


JUnit3 の場合は、以下のように UnitilsJUnit3 を継承してテストケースを作成します。

import org.unitils.UnitilsJUnit3;

public class MyTest extends UnitilsJUnit3 {
}}

ApplicationContext の設定

Unitils では Spring サポートにより、アノテーションにより ApplicationContex をDIすることができます。以下のようにすることで、applicationContext.xml と、テスト用に作成した applicationTestContext.xml の内容で作成された ApplicationContext がDIされます。Bean定義が重複する場合は、あとから設定したもので上書かれるため、通常利用する設定の変更分をテスト用の設定ファイルに定義することができます。

    @SpringApplicationContext({"applicationContext.xml", "applicationTestContext.xml"})
    private ApplicationContext applicationContext;


また、以下のように設定することで、スーパークラスの定義を、各サブクラスで上書き設定することができます。

@SpringApplicationContext("spring-beans.xml")
@RunWith(UnitilsJUnit4TestClassRunner.class)
public class BaseServiceTest {
}

public class UserServiceTest extends BaseServiceTest {

    @SpringApplicationContext("extra-spring-beans.xml")
    private ApplicationContext applicationContext;     
}

Spring Bean の注入

Unitils では Spring Bean の注入を行う3つの方法が提供されています。

@SpringBean("userService")
private UserService userService;

@SpringBeanByName
private UserService userService;

@SpringBeanByType
private UserService userService;

Bean 名を指定する @SpringBean アノテーション、Bean名による注入を行う@SpringBeanByName アノテーション、型による注入を行う@SpringBeanByType アノテーションがあります。 @SpringBeanByType を使用する場合は、setterメソッドが必要になります。

実際のテストケース

では、前回までで作成した Item Dao のテストケースを作成します。

import static org.unitils.reflectionassert.ReflectionAssert.*;
import org.junit.runner.RunWith;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.unitils.UnitilsJUnit4TestClassRunner;
import org.unitils.dbunit.annotation.DataSet;
import org.unitils.orm.hibernate.HibernateUnitils;
import org.unitils.spring.annotation.SpringApplicationContext;
import org.unitils.spring.annotation.SpringBeanByName;

@RunWith(UnitilsJUnit4TestClassRunner.class)
public class ItemDaoTest {

    @SpringApplicationContext({"applicationContext.xml", "applicationTestContext.xml"})
    private ApplicationContext applicationContext;
    
    @SpringBeanByName
    private ItemDao itemDao;

    @Test
    @DataSet
    public void testGet() {
        Item result = itemDao.get(1L);
        assertPropertyLenientEquals("name", "item1", result);

        result = itemDao.get(2L);
        assertPropertyLenientEquals("name", "item2", result);
    }
}

testGetメソッドに@DataSet アノテーションを付与しています。このアノテーションにより、テスト時に定義したデータ内容が自動的にデータベースにロードされます。ロードするファイルは、テストクラスを同じパッケージに、以下のような ItemDaoTest.xml ファイルを用意します。

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
    <item name="item1" />
    <item name="item2" />
</dataset>

この定義ファイルにより、itemテーブルの name カラムにitem1といったレコードがロードされます。テストを実行すると、グリーンとなるはずです。

@DataSet アノテーション

先に見た @DataSet アノテーションはメソッドに付与していましたが、以下のようにクラス単位で指定することもできます。この場合、全てのテストメソッドの実行前に定義データのロードが行われます。

@RunWith(UnitilsJUnit4TestClassRunner.class)
@DataSet
public class ItemDaoTest {


@DataSetアノテーションは通常テスト対象クラスを同名の定義ファイルを検索対象としますが、対象の定義ファイルを1つまたは複数指定することもできます。

@DataSet("ItemDaoTest_ages.xml")

@DataSet({"UserDAOTest_general.xml", "ConfigSettings.xml"})


また、以下のように指定すると、メソッドレベルのデータセットのみが有効になります。

@RunWith(UnitilsJUnit4TestClassRunner.class)
@DataSet
public class ItemDaoTest {

    @Test
    @DataSet("ItemDaoTest_ages.xml")
    public void testGet() {
    }

DataSetロードストラテジ

@DataSetアノテーションにてデータベースのレコードを操作する際のストラテジには以下が選択できます。

  • CleanInsertLoadStrategy: 現在存在するレコードを全て削除後、指定テーブルにインサーとを行う。デフォルトのストラテジ
  • InsertLoadStrategy: 単純インサーとを行うストラテジ
  • RefreshLoadStrategy: データセットの内容でデータベースの内容をリフレッシュする。これはデータセットで指定された列に値がある場合はアップデートし、行が存在しない場合はレコードがインサートされる
  • UpdateLoadStrategy: データセットの内容で既存のレコードをアップデートする。データベースに該当のレコードが存在しない場合は失敗する。


これらのストラテジは、unitils.properties に以下のように指定するか

DbUnitModule.DataSet.loadStrategy.default=org.unitils.dbunit.datasetloadstrategy.InsertLoadStrategy


@DataSetアノテーションにて以下のように指定することができます。

@DataSet(loadStrategy = InsertLoadStrategy.class)


次回
blog1.mammb.com

に続く。