所以我有一些端点的服务器代码,我想异步运行东西。为此,我使用了期货。有一些任务导致了结果,但也有昂贵的IO任务,所以我在火中执行它们并忘记了Future,如下:
import scala.concurrent.Future
val ec = scala.concurrent.ExecutionContext.global
Future {
Thread.sleep(10000)
println("Done")
}(ec)
println("Exiting now")
输出是:
import scala.concurrent.Future
ec: scala.concurrent.ExecutionContextExecutor = scala.concurrent.impl.ExecutionContextImpl@2315ca48
res0: scala.concurrent.Future[Unit] = scala.concurrent.impl.Promise$DefaultPromise@7d1e50cb
Exiting now
res1: Unit = ()
通常在服务器上这不是一个大问题,因为上下文在接收其他任务时继续运行,因此IO可以完成。但是当我测试时,测试结束并且内部的任务开始抛出,因为他们使用的服务变得不可用。
所以问题是:如何在不阻止主要执行的情况下等待这些火灾并忘记期货?
答案 0 :(得分:2)
为了说明我的答案,让我们假设您访问了一些fileService
以在即发即弃的部分加载文件,并且您使用Mockito(或其他模拟框架,这个想法保持不变)为您的单位试验。然后,我将在我的解释中提到的代码看起来像这样:
class SystemUnderTest(val fileService: MyFileService) {
def testedMethod(): GoodResult = {
val file = // ... some logic to extract file ...
Future {
fileService.uploadFile(file)
}
// ... other logic returning an instance of GoodResult
}
}
然后,在org.scalatest.Eventually
的测试组合中,做出如下的断言:
eventually {
verify(fileService).uploadFile(any())
}
它将确保主进程在可以验证已调用上传器服务(或implicit patienceConfig
定义的超时已过期)之前不退出。
当然,您总是可以选择在生产代码中返回您不等待的Future,并在测试中等待它。