単体テストを簡単に Unitils 〜導入編〜


Unitilsとは

Unitilsとは、Unitテストを容易で保守しやすくするオープンソースのライブラリです。JUnitTestNGDbUnitやEasyMockをより使いやすくするライブラリです。主な特徴は以下の通りです。

  • 一般的なテストで利用できるユーティリティを提供
  • Mockオブジェクトのサポート
  • 永続化層のテストサポート
  • EasyMock インテグレーションのサポート
  • Spring インテグレーションのサポート

Spring+Hibernateのプロジェクトでは相性が良いでしょう。本家は以下となります。
http://www.unitils.org/
現時点で3.0系も現れていますが基本的には同じなので、ここでは2.4について見ていきます。

Unitils の導入

ここでは、てっとり早くMavenでプロジェクトを作成します。別途 unitils-2.4-with-dependencies.zip をダウンロードも可です。

>mvn archetype:generate

Choose a number:  (・・・) 15: : 15
Define value for groupId: : etc9
Define value for artifactId: : unitils
Define value for version:  1.0-SNAPSHOT: :
Define value for package:  etc9: :
Confirm properties configuration:
groupId: etc9
artifactId: etc9-unitils
version: 1.0-SNAPSHOT
package: etc9
 Y: : Y


作成されたプロジェクトのpom.xmlを以下のように編集し unitils の依存ライブラリを取得します(JUnitは別途指定しないと取得されません)。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>etc9</groupId>
  <artifactId>etc9-unitils</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>etc9-unitils</name>
  <url>http://maven.apache.org</url>
  <dependencies>

  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.4</version>
    <scope>test</scope>
  </dependency>

  <dependency>
    <groupId>org.unitils</groupId>
    <artifactId>unitils</artifactId>
    <version>2.4</version>
  </dependency>

  </dependencies>
</project>


eclipseプロジェクトへの変換します。変換処理の過程で依存ライブラリを取得します。

> cd etc9-unitils
> mvn eclipse:eclipse


以下のライブラリが取得されました。

  • org.unitils:unitils:2.4
  • commons-logging:commons-logging:1.1
  • commons-dbcp:commons-dbcp:1.2.2
  • commons-pool:commons-pool:1.3
  • commons-lang:commons-lang:2.3
  • commons-collections:commons-collections:3.2
  • ognl:ognl:2.6.9
  • ant:ant:1.6.5
  • org.junit:junit:4.4


プロジェクトをEclipseにてインポートして導入は完了です。引き続き、本家のチュートリアルをベースに動作を確認していきます。

アサーションユーティリティ

Unitilsでは、JUnitアサーションを拡張する便利なユーティリティが提供されています。順に見ていきます。

同値性のテストを容易にするassertReflectionEquals

以下の様な単純なUserクラスを考えます。

public class User {
    private long id;
    private String name;

    public User(long id, String name) {
        this.id = id;
        this.name = name;
    }
}


User の値が同じ2つのインスタンスの同値性を確認したい場合、以下のようにするとテストは失敗となります。

User user1 = new User(1, "John");
User user2 = new User(1, "John");
assertEquals(user1, user2);

同一性にて比較が行われてしまうためです。同値性にて比較を行うには、User に equals メソッドを実装する必要があります。


こんな場合にはUnitils の org.unitils.reflectionassert.ReflectionAssert クラスの assertReflectionEquals が使用できます。ReflectionAssert クラスをstaticインポートし、

import static org.unitils.reflectionassert.ReflectionAssert.*;

以下のように assertReflectionEquals を使用するとクラスの同値性のテストを単純に以下のように書くことができます。

User user1 = new User(1, "John");
User user2 = new User(1, "John");
assertReflectionEquals(user1, user2);


また、assertReflectionEquals はフィールドがオブジェクトであっても再帰的に比較を行ってくれます。User クラスに対しても同値性の比較を行うことができます。

public class User {
    private long id;
    private String name;
    private Address address;

    public User(long id, String name, Address address) {
        this.id = id;
        this.name = name;
        this.address = address;
    }
}

public class Address {
    private String city;
    public Address(String city) {
    	this.city = city;
    }
}


以下のような比較が可能です。

User user1 = new User(1, "John", new Address("NY"));
User user2 = new User(1, "John", new Address("NY"));
assertReflectionEquals(user1, user2);


さらに、MapやListなどの各要素についても equals を実装せずとも同値性の比較が可能です。
また、assertReflectionEquals はプリミティブ型や、Integer や Long などのプリミティブラッパーの場合、== による比較を行います。すなわち、以下の比較は等しいと判断されます。

assertReflectionEquals(1, 1L);
assertReflectionEquals(2, new Long(2));

List<Double> myList = new ArrayList<Double>();
myList.add(1.0);
myList.add(2.0);
assertReflectionEquals(Arrays.asList(1, 2), myList);


次回はもう少し詳しくアサーションユーティリティについて見ていきます。