Mirageのユニットテスト支援機能

MockRunnerのJDBCMockの機能を参考に、MirageにDBレスでユニットテストを行うための機能を実装してみました。テストケースのサンプルはこんな感じ。

@Test
public void testGetBookById(){
  // 初期化
  MirageTestContext.initMirageTestContext();

  // MockSqlManagerをセット
  BookService bookService = new BookService();
  bookService.setSqlManager(new MockSqlManager());

  // MockSqlManagerの戻り値を設定
  Book book = new Book();
  book.setBookName("Mirage in Action");

  MirageTestContext.addResult(book);

  // テスト対象のメソッドを実行
  Book result = bookService.getBookById(new Long(100));

  // 戻り値を確認
  assertEquals("Mirage in Action", book.getName);

  // 実行されたSQLの数を確認
  MirageTestContext.verifySqlCount(1);

  // 実行されたSQLを確認
  MirageTestContext.verifySqlByRegexp(0,
    "SELECT .* FROM BOOK WHERE ID = \\? ORDER BY ID ASC");

  // SQLのパラメータの数を確認
  MirageTestContext.verifyParameterCount(0, 1);

  // SQLのパラメータの値を確認
  MirageTestContext.verifyParameter(0, 1, new Long(100));
}

発行されたSQLの検証は文字列の一致チェックで行いますが、改行や空白、大文字小文字の差異などは適当に吸収したうえで比較します。また、正規表現で比較することもできます(カッコやプレースホルダなどをいちいちエスケープしないといけないので若干面倒ですが…)。MirageTestContextをstaticインポートしておくといいかもしれません。
あと、いまのところストアドのユニットテストは未サポートです。MockSqlManagerのストアド実行用メソッド(call()やcallForList())を呼び出すとUnsupportedOperationExceptionがスローされます。
なんか微妙にもう一歩な気がするので少し変えるかもしれません。