scalatest - 使用 fallbackTo 测试 Future[S] 的方法
scalatest - test a method of Future[S] with fallbackTo
前提:当我的 API 响应对 User 对象的请求时,我想尝试使用 case class PartnerView(id: String, vipStatus: Option[Boolean], latestSession: Option[Timestamp]
的属性来丰富它。由于数据库有时可能不可靠,我使用 fallbackTo
提供可选值,因此不会在用户 JSON 响应中显示它们。
到目前为止,以下实现似乎有效(运行 通过邮递员的请求 returns 用户 JSON 没有可选值)但我的单元测试会抱怨,好像我有未捕获的异常。
服务class:
class Service(repo: Repository) {
def get(id: String): Future[Partner] = {
val account = repo.getAccount(id)
val getLatestSession = repo.getLatestSession(id)
val partnerView = (for {
account <- getAccount
latestStartTime <- getLatestSession.map {
case Some(x) => x.scheduledStartTime
case _ => None
}
} yield PartnerView(partnerId, account.vipStatus, latestStartTime))
.fallbackTo(Future.successful(PartnerView(id, None, None)))
partnerView
}
}
存储库class:
class Repository(database: DatabaseDef, logger: LoggingAdapter) {
def getAccount(id: String): Future[Account] = database.run((...).result.head)
.recover {
case e: Exception =>
logger.error(e, "DB Server went down")
throw e
}
def getLatestSession(id: String): Future[Option[Session]] = database.run((...).result.headOption)
.recover {
case e: Exception =>
logger.error(e, "DB Server went down")
throw e
}
}
单元测试:
class ServiceSpec extends AsyncFlatSpec with AsyncMockFactory with OneInstancePerTest {
val mockRepo = mock[Repository]
val service = new Service(mockRepo)
behaviour of "Service"
it should "get an empty PartnerView when the repository get an Exception" in {
(mockRepository.getAccount _)
.expects("partner")
.throwing(new Exception)
service.get("partner")
.map(partnerView => assert(partnerView.id == "partner" && partnerView.vipStatus.isEmpty))
}
}
测试将失败并显示消息
Testing started at 5:15 p.m. ...
java.lang.Exception was thrown.
{stacktrace here}
我期待 Exception
到
通过将模拟设置更改为以下,测试 运行 成功:
it should "get an empty PartnerView when the repository get an Exception" in {
(mockRepository.getAccount _)
.expects("partner")
.returning(Future.failed(new Exception))
...
}
因为 recover
方法将 Exception
包装在 Future
中
来源:
前提:当我的 API 响应对 User 对象的请求时,我想尝试使用 case class PartnerView(id: String, vipStatus: Option[Boolean], latestSession: Option[Timestamp]
的属性来丰富它。由于数据库有时可能不可靠,我使用 fallbackTo
提供可选值,因此不会在用户 JSON 响应中显示它们。
到目前为止,以下实现似乎有效(运行 通过邮递员的请求 returns 用户 JSON 没有可选值)但我的单元测试会抱怨,好像我有未捕获的异常。
服务class:
class Service(repo: Repository) {
def get(id: String): Future[Partner] = {
val account = repo.getAccount(id)
val getLatestSession = repo.getLatestSession(id)
val partnerView = (for {
account <- getAccount
latestStartTime <- getLatestSession.map {
case Some(x) => x.scheduledStartTime
case _ => None
}
} yield PartnerView(partnerId, account.vipStatus, latestStartTime))
.fallbackTo(Future.successful(PartnerView(id, None, None)))
partnerView
}
}
存储库class:
class Repository(database: DatabaseDef, logger: LoggingAdapter) {
def getAccount(id: String): Future[Account] = database.run((...).result.head)
.recover {
case e: Exception =>
logger.error(e, "DB Server went down")
throw e
}
def getLatestSession(id: String): Future[Option[Session]] = database.run((...).result.headOption)
.recover {
case e: Exception =>
logger.error(e, "DB Server went down")
throw e
}
}
单元测试:
class ServiceSpec extends AsyncFlatSpec with AsyncMockFactory with OneInstancePerTest {
val mockRepo = mock[Repository]
val service = new Service(mockRepo)
behaviour of "Service"
it should "get an empty PartnerView when the repository get an Exception" in {
(mockRepository.getAccount _)
.expects("partner")
.throwing(new Exception)
service.get("partner")
.map(partnerView => assert(partnerView.id == "partner" && partnerView.vipStatus.isEmpty))
}
}
测试将失败并显示消息
Testing started at 5:15 p.m. ...
java.lang.Exception was thrown.
{stacktrace here}
我期待 Exception
到
通过将模拟设置更改为以下,测试 运行 成功:
it should "get an empty PartnerView when the repository get an Exception" in {
(mockRepository.getAccount _)
.expects("partner")
.returning(Future.failed(new Exception))
...
}
因为 recover
方法将 Exception
包装在 Future
来源: