我正在测试某些Future
失败的情况,并以两种不同的方式进行了尝试,一种有效:
intercept[NoSuchElementException] {
Await.result(dao.findById("some_id"), Duration.Inf)
}
和没有:
a[NoSuchElementException] should be thrownBy dao.findById("some_id")
以前发生在我身上,我正试图弄清楚为什么。
很乐意得到一些帮助来理解这一点。
findById
仅在失败时抛出NoSuchElementException
:
def findById(id: String): Future[Person] = {
collection.find(json(Vendor.PersonId -> id))
.requireOne[Person] recover {
case NoSuchResultException => throw new NoSuchElementException
}
}
答案 0 :(得分:3)
您面临的问题是Future
的处理不正确。
给出以下定义:
def findById(id: String): Future[Person] = {
collection.find(json(Vendor.PersonId -> id))
.requireOne[Person] recover {
case NoSuchResultException => throw new NoSuchElementException
}
}
recover
会将NoSuchResultException
映射到throw new NoSuchElementException
,但始终包裹在Future
内。
这意味着返回的对象将是失败的Future
,并且该方法不会引发任何异常。
要处理这种情况,您可以例如在scalatest中将测试类与ScalaFutures
特性一起混合。这样可以帮助您像
dao.findById("some_id").failed.futureValue should be a[NoSuchElementException]
答案 1 :(得分:2)
考虑这是否是实现:
def findById(id: String): Future[Person] = Future {
Thread.sleep(1000)
throw new NoSuchElementException()
}
调用findById
本身不会引发异常。它立即返回了这个未来。异常会在返回的Future
中引发,因此只有在您对结果进行Await
或以其他方式访问将来的结果时才会出现该异常。