S2UnitでDB検索のテスト

CRUD(Create Reference Update Delete)ってなんて読み方が一般的なんだろう。私は”クラッド”なのだけれど”クルド”って読む人もいるらしい。これは、情報は”生成”され、”参照”され、”更新”され、”削除”される、って意味の言葉だけど、この中で何が一番多いかと言えば、言わずもがな”参照”。ということで、今回はS2Unitを用いてDB検索のテストをしたいと思います。

テストの考え方

  1. テスト用の空のDBを用意する。
  2. テストの為に必要なデータをExcelから読み取ってテーブルに反映。
  3. 検索処理を実行(←これが正しいかテスト)
  4. 検索結果で取得されたエンティティの主キーが意図したものかを確認する。

今回作成したリソース

EmployeeService.java
public class EmployeeService {

    public JdbcManager jdbcManager;

    public List<Employee> findByDepartmentId(Integer departmentId) {

        List<Employee> result = jdbcManager.from(Employee.class)
                                    .where("departmentId = ?", departmentId)
                                    .getResultList();
        return result;
    }
}

部署IDを元に社員レコードを取得しようというこのメソッドが今回のテスト対象。しかし、S2JDBCって知らない人にも、どういう処理をやってるのかが理解しやすいよね。

EmployeeServiceTest.java
public class EmployeeServiceTest extends S2TestCase {

    private EmployeeService employeeService;

    public void setUp() {
        include("test.dicon");
    }

    public void test_findByDepartmentIdTx() {

        readXlsWriteDb("EmployeeServiceTestInit.xls");

        List<Employee> employeeList = employeeService.findByDepartmentId(1);

        // EmployeeId=1,2のレコードが取得されること
        assertEquals(2, employeeList.size());
        assertEquals(1, employeeList.get(0).employeeId.intValue());
        assertEquals(2, employeeList.get(1).employeeId.intValue());
    }
}

EmployeeServiceのテストクラス。まず、readXlsWriteDb()で、引数に指定されたパスのExcelファイルを読み取ってテーブルに書き込んでいる。その後、テスト対象のメソッドを呼び出し、結果エンティティ(レコード)が正しいことを確認している。カラム全てを確認するのは効率が悪いので、主キーのみ確認している。

そういえば昨日のエントリーでは書き忘れたけど、S2TestCaseを継承したテストクラスでは、メソッドの最後に"Tx"を付けておくとメソッド終了時に自動的にDBをロールバックしてくれる。こうすれば、テーブルを汚さないでテストが行える。”立つ鳥跡を濁さず”ってやつだね。

EmployeeServiceTestInit.xls



シートは、社員テーブル用と部署テーブル用の2枚で構成。今回のテストでは、社員テーブルしか使わないけど、社員テーブルでは部署テーブルを参照しているので、外部キーで参照している部署レコードが存在しないと挿入できない。readXlsWriteDb()ではシートの定義順に挿入処理が行われるそうなので、今回は部署テーブル用のシートを先にしている。

テスト結果

スクリーンショットは載せないけどグリーンです。ところで、今回は一発でグリーンになったのだけれど、やっぱり最初からグリーンだと逆に不安になるね。テスト駆動で、レッド→グリーン→リファクタリング、という考え方は正しいのかも。

補足

readXlsWriteDb()は、テストクラスと同じパッケージに置いておけば、今回のようにファイル名だけでOK。テストリソースはテストクラスに近い位置にあったほうがいいと思うので、このやり方を推奨。

あと、Eclipseを使っている場合の注意として、パッケージエクスプローラの表示を更新しないと、Excelファイルを更新しても正しく認識されないことがある(たぶんEclipseのキャッシュ機能のせい)。なので、テスト前にパッケージエクスプローラでF5を押すなどして更新するか、ワークスペースを常に最新に更新する設定にしておくと良い。