尝试并发执行我想知道如何实际测试它。 执行流程具有副作用,并且会创建期货以包装独立的执行/处理。
一直在寻找一些关于如何正确单元测试以下方案的好例子( foo
和 bar
是我希望的方法试验):
第1场
def foo : Unit = { Future { doSomething } Future { doSomethingElse } } private def doSomething : Unit = serviceCall1 private def doSomethingElse : Unit = serviceCall2
情景动机
foo
立即返回,但会调用2个期货执行单独的任务(例如,将分析和存储记录保存到数据库)。这些服务调用可以被模拟,但是我试图测试的是这些服务在我将它们包装在Future
中后被调用
方案#2
def bar : Unit = { val futureX = doAsyncX val futureY = doAsyncY for { x <- futureX y <- futureY } yield { noOp(x, y) } }
情景动机
从可以同时执行的长时间运行计算开始(例如,获取总访问者数量并获取常用的User-Agent
标题到我们的网站)。将结果组合在一些其他操作中(在这种情况下,Unit
方法只会抛出值)
注意我熟悉演员和测试演员,但鉴于上面的代码,我想知道什么是最合适的方法(包括重构)
编辑 我目前正在做的事
implicit value context = ExecutionContext.fromExecutor(testExecutor) def testExecutor = { new Executor { def execute(runnable : Runnable) = runnable.run } }
此ExecutionContext
实现不会将Future
作为单独的线程运行,整个执行将按顺序完成。这种感觉就像一个黑客,但基于电子僧侣答案,似乎其他解决方案更像是相同。
答案 0 :(得分:2)
一种解决方案是使用DeterministicExecutor。不是一个scalaesque解决方案,但应该这样做。
答案 1 :(得分:0)
如果您使用的是ScalaTest,请查看:http://doc.scalatest.org/2.0/index.html#org.scalatest.concurrent.Futures
Specs2也支持测试期货: http://etorreborre.github.io/specs2/guide/org.specs2.guide.Matchers.html
答案 2 :(得分:0)
ScalaTest 3.x支持异步非阻塞测试。