I have the following function which I want to test:
def filterFoo(FooColumnName: String, Foo: Seq[Any]): DataFrame = {
/* validate input parameters */
require(Option(FooColumnName).isDefined)
require(Option(Foo).isDefined)
require(df.columns.contains(FooColumnName))
df.filter(col(FooColumnName).isin(Foo:_*))
I have written the following test:
@Test(expected = classOf[IllegalArgumentException])
def testFilterFoorWrongColumnName(): Unit ={
val df = data.toDF(columns:_*)
df.filterFoo(FooColumnName = "foo", Foo = competitors)
}
If FooColumnName does not exists in Data frame it would throw IllegalArgumentException. I am getting this exception but it is failing the test because of this. I get this error when I run the test:
java.lang.IllegalArgumentException: requirement failed
CodePudding user response:
The trick is to reify the exception into a value, which, thankfully, is something that is extremely idiomatic in Scala. scala.util.Try
is in the standard library and exceptionally useful for this:
import scala.util.{ Failure, Success, Try }
@Test(expected = classOf[IllegalArgumentException])
def testFilterFoorWrongColumnName(): Unit ={
val df = data.toDF(columns:_*)
val attempt = Try { // note the capital T, this is not the keyword try...
df.filterFoo(FooColumnName = "foo", Foo = competitors)
}
// apologies, I don't know JUnit at all...
attempt match {
case _: Success =>
failTheTest // should have been a failure
case Failure(ex) => // ex is the thrown exception
// can check that the exception is an IllegalArgumentException or whatever
doChecksOnException
}
}
How it works is that a Try[T]
is either a Success
wrapping a T
or a Failure
wrapping a Throwable
. Try { }
wraps the code in a try
block and catches the exception; if it's a NonFatal
exception, that exception goes into the Failure
. There are some other good reasons to use Try
(it has some nicely compositional properties), but those are out of the scope of this answer.