Scalatest提供了一些使用Future
s的方法.
选项1: isReadyWithin
import org.scalatest.concurrent.ScalaFutures._
import scala.concurrent.duration._
calculate(1, 3).isReadyWithin(1.second) should be(true)
Run Code Online (Sandbox Code Playgroud)
如果你想在这里做一些返回值,你可以使用whenReady
:
implicit val patienceConfig = PatienceConfig(1.second)
def calculateWithResult(i: Int, j: Int): Future[Int] = ???
whenReady(calculateWithResult(1,3)) { result =>
result should be(4)
}
Run Code Online (Sandbox Code Playgroud)
您需要一个隐含PatienceConfig
的范围,用于指示whenReady
何时因超时而导致测试失败.我相信其中一个scalatest
库中有一个默认值,但选择的时间段很短 - 大约10毫秒 - 并且通常会导致测试不稳定.
选项2: AsyncXSpec
有Async
品种的FlatSpec
,FreeSpec
,FunSpec
等特点.除了任何测试现在必须返回类型值之外,它们的工作方式与它们的同步变量非常相似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
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
同样,您可以在此处针对结果运行测试.请注意,此变体意味着测试类中的每个测试都必须返回a Future
,因此如果要混合同步和异步测试,则不是很好.我老实说也不确定如何AsyncXSpec
选择超时值.
选项不要: Await.result
我建议不要使用,Await.result
因为它会阻止线程持续时间.据我所知,上面两个选项的设计使得异步测试可以轻松并行运行.
注意事项:
在进行异步测试时,您希望对超时非常小心.太长了,如果出现问题,你的测试可能会持续多年.太短了,你的测试会很脆弱.并且程序可能在不同的环境中执行不同的操作,因此您可能会发现在本地计算机上完全足够的超时使构建服务器上的测试在5%的时间内失败.小心!