scala - 断言返回类型为 Future[Unit] 的 scala 方法的最佳方法是什么
问题描述
我有一个方法。此方法可能返回 Future.failed(.....) 或 Future.successful(())。
def 计算(x: Int, y: Int): Future[Unit] = { ........ }
现在我需要测试这个方法。Future.successful(())
为验证case的测试断言的最佳方法是什么 。
解决方案
Scalatest 提供了几种使用Future
s 的方法。
选项1: isReadyWithin
import org.scalatest.concurrent.ScalaFutures._
import scala.concurrent.duration._
calculate(1, 3).isReadyWithin(1.second) should be(true)
如果你想在这里做一些返回值的事情,你可以使用whenReady
:
implicit val patienceConfig = PatienceConfig(1.second)
def calculateWithResult(i: Int, j: Int): Future[Int] = ???
whenReady(calculateWithResult(1,3)) { result =>
result should be(4)
}
您需要一个隐含PatienceConfig
的范围来告诉whenReady
测试何时因超时而失败。我相信其中一个库中有一个默认的scalatest
库,但是选择的时间段很短——大约 10 毫秒——并且通常会导致不稳定的测试。
选项 2: AsyncXSpec
有Async
多种FlatSpec
, FreeSpec
,FunSpec
等特征。它们的工作原理与它们的同步变体非常相似,只是现在任何测试都必须返回 type 的值Future[Assertion]
。例如:
class Test extends AsyncFreeSpec {
"An asynchronous method" - {
"should succeed" in {
calculate(1,3).map { _ =>
// just want to make sure the future completes
succeed
}
}
}
}
同样,您可以在此处针对结果运行测试。请注意,此变体意味着您的测试类中的每个Future
测试都必须返回 a ,因此如果您想混合同步和异步测试,那就不好了。老实说,我也不确定如何AsyncXSpec
选择它的超时值。
选项不要: Await.result
我建议不要使用Await.result
它,因为它会在持续时间内阻塞线程。据我所知,上述两个选项的设计目的是使异步测试可以轻松地并行运行。
注意事项:
在进行异步测试时,您需要非常小心超时。时间太长,如果出现问题,您的测试最终可能会挂起很长时间。太短了,你的测试会很不稳定。并且程序在不同环境中的执行可能会有所不同,因此您可能会发现在本地计算机上完全足够的超时会使构建服务器上的测试失败 5% 的时间。当心!
推荐阅读
- quickfix - 如何使用 quickFix/n 包中的 FIXT11 功能
- laravel - 如何将 laravel 表单删除转换为字符串以在返回控制器上使用它?
- amazon-web-services - 跨不同区域路由来自多个 VPC 的传出流量
- xml - 我有一个包含多条记录的大型 xml 文件。我想使用 postgresql 查询将记录一一获取为单独的 xml 文件
- button - Xamarin.Forms 按钮在触摸后变为禁用
- android - createAppContainer not working even after exporting
- javascript - 如何在 JSBin 模板中使用“期望”?
- security - JavaEE + JBoss:验证所有部署的战争文件
- html - NativeScript Angular:如何使用 FormattedString 使 Span 可点击
- php - 单击禁用按钮时禁用数据行