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.
