I'm trying to write a property that basically states "it should either not throw an exception, or throw one of a list of possible exceptions" using ScalaTest and it's GeneratorDrivenPropertyChecks
which in turn uses scalatest. The issue is that I wasn't able to combine the noException
with an logical or, so the best I could come with is this ugly test:
it should "not throw unexpected exceptions" in {
forAll { (s: String) =>
try { parse(s) }
catch { case e:Throwable => e shouldBe a [ParsingFailedException] }
true shouldBe true // prevent compile error
}}
What I would like to see instead would read more like
it should "not throw unexpected exceptions" in {
forAll { (s: String) => {
(noException should Be thrownBy) or (a [ParsingFailedException] shouldBe thrownBy) { parse(s) }
}}
Since we want to use the exception as a value and not to control an exceptional flow, we could use
scala.util.Try
and make assertions on the value ofTry
. So instead of callingparse(s)
we could callTry(parse(s))
.Unfortunately, because the values are wrapped now, I can't think of a clean way to assert predicates on them other than writing a custom matcher. For your specific example, a custom matcher could look as follows:
Since
Try
is covariant, we can define the generic type of our custom matcher to beTry[Any]
. The matcher matches only instances ofFailure[Any]
that fail with an exception of the provided type. Now, we could call this as:Now, if a non-expected exception happens, the error could look as follows: