如何测试期货是否在Scala中按顺序运行?

问题描述 投票:0回答:1

假设我有此方法:

def callApis(f1, f2, f3):Future[Result] {
    for {
        a <- Future { f1 }
        b <- Future { f2 }
        c <- Future { f3 }
    } yield Result(a,b,c)
}

如果您熟悉scala,您将知道for块中的行将按顺序执行。更具体地说,将首先计算a。然后,当我们得到a的结果时,代码将计算b。然后,当我们得到b的结果时,代码将计算c。

[[我的问题是,您如何编写一个UNIT TEST,以确保在计算b之前总是先计算a,而在计算c之前总是先计算b?我担心的是,如果有人对期货的了解不多在斯卡拉工作。他们可能不小心使此代码异步运行。

我的意思是人们可以

偶然地

做这样的事情,这使得a,b,c可以异步计算((我不想让人们去做)def callApis(f1, f2, f3):Future[Result] { val fut1 = Future { f1 } val fut2 = Future { f2 } val fut3 = Future { f3 } for { a <- fut1 b <- fut2 c <- fut3 } yield Result(a,b,c) }
scala unit-testing asynchronous future
1个回答
0
投票
也许尝试定义单线程执行上下文,并要求在应该串行执行的块中使用它。例如,

trait SerialExecutionContext extends ExecutionContext { val singleThreadPool = Executors.newFixedThreadPool(1, (r: Runnable) => new Thread(r, s"single-thread-pool")) val serialEc = ExecutionContext.fromExecutor(singleThreadPool) override def execute(runnable: Runnable): Unit = serialEc.execute(runnable) override def reportFailure(cause: Throwable): Unit = serialEc.reportFailure(cause) } def callApis()(implicit ec: SerialExecutionContext): Future[Result] = { val fut1 = Future { ...doSomething... } val fut2 = Future { ...doSomething... } val fut3 = Future { ...doSomething... } for { a <- fut1 b <- fut2 c <- fut3 } yield Result(a,b,c) }

现在callApis仅在我们可以证明在编译时证明存在串行执行上下文的情况下才可以求值。由于体内只有一个线程,因此只有在前一个线程完成后,才能强制启动期货。
© www.soinside.com 2019 - 2024. All rights reserved.