scalatest 拦截 vs [Exception] 应该被抛出

scalatest intercept vs a[Exception] should be thrownBy

我正在测试一些失败的 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
    }
  }

考虑这是否是实施:

def findById(id: String): Future[Person] = Future {
  Thread.sleep(1000)
  throw new NoSuchElementException()
}

调用findById本身不会抛出异常。它returns这个未来马上。异常在 returns 的 Future 中抛出,因此它仅在您 Await 处理结果时才会出现,或者以其他方式访问未来的结果。

您遇到的问题是 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并且该方法不会抛出任何异常。

要处理这种情况,例如,您可以将测试 class 与 scalatest 中的 ScalaFutures 特征混合。这可以帮助您像

一样处理未来
dao.findById("some_id").failed.futureValue should be a[NoSuchElementException]