当前位置: 首页 > 知识库问答 >
问题:

如何在Scala单元测试中指定异步调用的确切执行顺序?

夏俊杰
2023-03-14

我在Scala中为期货编写了许多不同的单元测试。所有异步调用都使用执行上下文。为了确保异步调用始终以相同的顺序执行,我需要延迟一些任务,这相当困难并且会减慢测试速度。执行程序可能仍(取决于其实现)先完成某些任务,然后再完成其他任务。

测试具有特定执行顺序的并发代码的最佳方式是什么?例如,我有以下测试用例:

"firstSucc" should "complete the final future with the first one" in {
    val executor = getExecutor
    val util = getUtil
    val f0 = util.async(executor, () => 10)
    f0.sync
    val f1 = util.async(executor, () => { delay(); 11 })
    val f = f0.firstSucc(f1)
    f.get should be(10)
  }

其中delay是< code > def delay()= thread . sleep(4000),而< code>sync同步未来(调用< code>Await.ready(future,Duration。Inf))。这就是我要确保f0已经完成,f1在f0之后完成的方式。f0完成还不够,因为< code>firstSucc可能会改变未来。因此,f1应延迟到检查< code>f.get之后。

另一个想法是从promise中创造未来,并在某个时间点完成它们:

  "firstSucc" should "complete the final future with the first one" in {
    val executor = getExecutor
    val util = getUtil
    val f0 = util.async(executor, () => 10)
    val p = getPromise
    val f1 = p.future
    val f = f0.firstSucc(f1)
    f.get should be(10)
    p.trySuccess(11)
  }

有没有更简单/更好的方法来定义执行顺序?也许是另一个执行服务,可以配置提交任务的顺序?对于这种特定的情况,将第二个期货延迟到结果被检查之后可能就足够了,但是在某些情况下,所有的期货都必须按照一定的顺序完成。

完整的代码可以在这里找到:https://github.com/tdauth/scala-futures-promises

测试用例是这个类的一部分:https://github.com/tdauth/scala-futures-promises/blob/master/src/test/scala/tdauth/futuresandpromises/AbstractFutureTest.scala

这个问题可能与此相关,因为Scala可以使用Java Executor服务:使用Executor Service控制任务执行顺序

共有1个答案

黎阳冰
2023-03-14

对于大多数简单的情况,我认为一个单线程执行器就足够了——如果你一个接一个地开始你的未来,它们将被连续执行,并以同样的顺序完成。

但看起来你的问题实际上比你描述的更复杂:你不仅在寻找一种方法来确保一个未来比另一个晚完成,而且在一般情况下,使一系列任意事件按特定顺序发生。例如,您问题中的代码片段验证了第二个未来在第一个未来完成后开始(顺便说一句,我不知道在这种情况下,延迟是为了什么)。

您可以使用最终等待特定事件发生,然后再继续:

   val f = Future(doSomething) 
   eventually { 
      someFlag shouldBe true
   }
   val f1 = Future(doSomethingElse) 
   eventually { 
      f.isCompleted shouldBe true
   }
   someFlag = false   
   eventually { 
      someFlag shouldBe true
   }

   f1.futureValue shoudlBe false
 类似资料:
  • 在试验并发执行时,我想知道如何实际测试它。执行流程具有副作用性质,创建未来是为了包装独立的执行/处理。 我一直在寻找一些关于如何正确单元测试的好例子,下面的场景(和是我希望测试的方法): 情景#1 情景动机 立即返回,但调用两个执行单独任务的未来(例如,保存分析并将记录存储到数据库)。这些服务调用可以被模拟,但我试图测试的是,一旦我将它们包装在s中,这两个服务都会被调用 场景#2 情景动机 从可以

  • 问题内容: 我有一个测试用例,其中添加了一个实体,对其进行了更新并删除了该实体。因此,执行顺序在这里很重要。我希望它是: 创造 更新资料 删除 奇怪的是,对于仅一个测试用例(15个测试用例),JUnit按以下顺序执行它: 删除 更新资料 创造 。 如何告诉JUnit按特定顺序执行它们?在其他情况下,JUnit可以正常工作(串行执行)。在这种情况下,为什么JUnit表现怪异? 以下相关代码段: 变得

  • 问题内容: 我正在使用带有eclipse的junit编写功能测试。 当运行单个测试时,它将按照我在类中设置它们的顺序运行。 例如。 但是,当我将此测试作为套件的一部分运行时(在包中),顺序是随机的。 例如,它将执行验证,然后删除用户,然后删除joinuserToRoom然后创建用户。 我在套件中的测试并不相互依赖。但是,测试中的每个单独测试都取决于它们以正确的顺序运行。 有什么办法可以实现? 谢谢

  • 好吧,我不想再找这方面的好消息了。我有一系列的单元测试调用一个静态类,这个类一旦初始化,就会设置不能(或者我不想)更改的属性。

  • 本文向大家介绍js循环中调用异步的方法,如何确保执行结果的顺序是正确的?相关面试题,主要包含被问及js循环中调用异步的方法,如何确保执行结果的顺序是正确的?时的应答技巧和注意事项,需要的朋友参考一下 An example:

  • 我有一个方法如下所示: 我试图这样进行单元测试: 在完成模拟的LookUpIdAsync之前,将调用我的断言。在我的普通代码中,这正是我想要的。但是对于我的单元测试,我不希望这样。 我正在使用BackgroundWorker转换为Async/Await。对于后台工作人员,这项功能正常运行,因为我可以等待后台工作人员完成。 但是似乎没有办法等待异步无效方法... 如何对该方法进行单元测试?