Reputation: 13
I've checked the answers specified in the post How to test a Try[T] with ScalaTest correctly?
But if I had to do any assertions after the function call or if I have to check the assertions within a for { } yield { }
block then I'm following the below given approach:
def test(a: Int, b: Int): Try[Int] = Try {
a / b
}
it.should("succeed").in {
(for {
res <- test(0, 1)
} yield {
assert(res === 0)
// assume more assertions are to be made
}) match {
case Success(value) => value
case Failure(exception) => fail(exception)
}
}
it.should("fail").in {
test(1, 0).failure.exception.getClass.mustBe(classOf[java.lang.ArithmeticException])
}
The problem with above approach is that, for the success case if any issue happens in the unit test logic then it'll show the error pointing to the line case Failure(exception) => fail(exception)
and not on the line where the actual error occurred. If the test case is huge then it'll be difficult for the user to find where exactly the error occurred.
So is there a better way to unit test the functions which returns a Try[T]
without moving the assertions outside the for { } yield { }
block?
Upvotes: 1
Views: 1010
Reputation: 27356
The TryValues
trait (documented here) is designed to help with this:
class MyTestSpec extends FlatSpec with Matchers with TryValues {
"tryTest" should "succeed" in {
// Normal tests
test(0, 1).isSuccess shouldBe true
test(1, 1).isFailure shouldBe true
// Use TryValues conversions
test(0, 1).success.value shouldBe 0
test(1, 1).failure.exception should have message "should be zero"
}
}
Upvotes: 3