First, I need this async test to get compiled.
Second, some assertions are made conditionally, depending on whether options are defined, while others are not.
Third, I'd like the test to fail fast, that is, on the first failed assertion.
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers._
import scala.concurrent.Future
class MultipleOptionAsyncTests extends AsyncFlatSpec {
object SomeGlobalContextHolder {
val ctx: Option[SomeGlobalContext] = Some(new SomeGlobalContext)
}
class SomeGlobalContext {
def apply(key: String): Set[String] = Set("values that have been set for the key")
}
case class User (id: String, ssoId: Option[String])
type TypeOfResult = String
def methodBeingTested(user: User): Future[TypeOfResult] = Future.successful("some result")
it should "get compiled and test ALL assertions" in {
val user = User("id", Some("ssoId"))
methodBeingTested(user).map { result =>
result should be "some result"
SomeGlobalContextHolder.ctx.foreach { ctx =>
user.ssoId.foreach { ssoId =>
ctx("ssoId") should contain (ssoId) // fail the entire test if this assertion fails
}
ctx("user") should contain (user.id) // fail the entire test if this assertion fails
}
}
} // expected Future[Assertion], but facing Future[Unit]
}
My mate suggested several approaches, and I came up with the following:
it should "get compiled and test ALL assertions" in {
val user = User("id", Some("ssoId"))
methodBeingTested(user).map { result =>
def assertFor[T](opt: Option[T]) = opt.fold(succeed) _
result should be "some result"
assertFor(SomeGlobalContextHolder.ctx) { ctx =>
ctx("user") should contain (user.id)
assertFor(user.ssoId) { ssoId =>
ctx("ssoId") should contain (ssoId)
}
}
}
}
Alternatively, you might consider using the pure fold
.