uehaj's blog

Grな日々 - GroovyとかGrailsとかElmとかRustとかHaskellとかReactとかFregeとかJavaとか -

例外が発生することを期待するassert

注:本記事は、車輪の再発明です。

「例外が発生することを期待するassert」を書きたいときがあります。これを書きたいケースが生じるのは、テストコードや、サンプルコードを書くときです。例外のthrow/catchのコストを考えると、プロダクトコード中にはあまり書かない方がいい種類のassertです。

JUnit4の場合、@Test(expectedExceptions = Exception.class)のようにテストケースメソッドにアノテーションを指定して「例外が発生することを期待する」ことを指定することもできますが、上がってくることを指定できるのは1メソッドあたり1回だし、上がってきた例外インスタンスに対する更なる吟味を行うこともできません。

ということでGroovyでつくってみました。

def assertCatch(Class e, Closure c) {
  def result;
  try{
    c.call()
    assert false
  } catch(Throwable t) {
    assert e.isInstance(t)
    result = t
  }
  result
}

こんな風に使います。

assertCatch(ArrayIndexOutOfBoundsException) { ([1,2,3] as int[])[5] }

戻り値は上がってきた例外ですので、

e = assertCatch(ArrayIndexOutOfBoundsException) { ([1,2,3] as int[])[5] }
assert e.message  == "5"

のように吟味することもできます。

(追記) id:kskyさんに指摘いただきましたが、GroovyTestCase.shouldFailが「例外発生を期待するassert」に相当します。まあこちらはGroovyTestCaseのサブクラスではなくても使えるということで。

しかしながら、さらにぐぐると。id:nobeansさんも同じことを...。

「こんなの普通に思いつくことだから、もしかしてすでにある?」あたた。