Thursday, November 21, 2013

Assert T

Here is some trick for getting over type erasure in Scala.


I want to create the following method that will expect an exception of particular type:

def assertT[T <: Throwable ](body: =>Unit) = {
  try {
    body
    assert(false)
  } catch {
    case e : T => assert(true)
  }
}

But due to type erasure, the case condition ( : T ) will be never checked. Scala compiler will warn you with "abstract type pattern T is unchecked since it is eliminated by erasure".

To fix this, you need a runtime class info and runtime class check:

def assertT[T <: Throwable : ClassTag](body: =>Unit) = {
  val clazz = implicitly[ClassTag[T]].runtimeClass
  try {
    body
    assert(false)
  } catch {
    case e if clazz.isInstance(e) => assert(true)
  }
}

where ClassTag is scala.reflect.ClassTag