octavian octavian - 1 month ago 6
Scala Question

Assert that the correct exception is thrown

I have a method

ESV.allocate(BLOCK_NUMBER + 1)
that only returns an
Exception
wrapped in a
Failure
:

Failure(new Exception("Tried to allocate more than available memory"))


However, I'm not sure how to test that.

I tried using FunSuite and I put this in my unit test:

assert(ESV.allocate(BLOCK_NUMBER + 1) == Failure(new Exception("Tried to allocate more than available memory")))


However, the test fails with this message:

Failure(java.lang.Exception: Tried to allocate more than available memory) did not equal Failure(java.lang.Exception: Tried to allocate more than available memory)


This is probably because I am instantiating a different
Exception
object in the assert, and it doesn't compare as equal to the one returned by the method I am testing.

So how can I check the result returned by the method?

Answer

Compare classes instead of comparing absolute values.

assert(ESV.allocate(BLOCK_NUMBER + 1).getClass == classOf[Failure[_]])

if you want to check the exception message also then

assert((ESV.allocate(BLOCK_NUMBER + 1).getClass == classOf[Failure[_]]) && (ESV.allocate(BLOCK_NUMBER + 1).failed.get.getMessage == Failure(new Exception("Tried to allocate more than available memory")).failed.get.getMessage))

or

assert((ESV.allocate(BLOCK_NUMBER + 1).getClass == classOf[Failure[_]]) && ESV.allocate(BLOCK_NUMBER + 1).failed.get.getMessage == new Exception("Tried to allocate more than available memory").getMessage)

Better solution

implicit class TryUtils[A](something: Try[A]) {
  def compare[B](other: Try[B]): Boolean = {
    (something, other) match {
      case (Success(a), Success(b)) => a == b
      case (Failure(a), Failure(b)) => a.getClass == b.getClass && (a.getMessage == b.getMessage)
      case (_, _) => false
    }
  }
}

Usage:

assert(ESV.allocate(BLOCK_NUMBER + 1) compare Failure(new Exception("Tried to allocate more than available memory")))