为什么当我执行 Await.result 时,我的 Scala 异步测试永远不会完成?

2023-12-27

我创建了一个简单的测试场景来显示这一点:

class Test extends AsyncFunSuite {

  test("async test") {
    val f = Future {
      val thread = new Thread {
        override def run(): Unit = {
          println("OKAYY")
        }
      }
      thread.start()
    }

    Await.result(f, Duration.Inf)
    Future {
      assert(true)
    }
  }

}

执行此操作时,测试将永远运行并且永远不会完成。


您将在 ScalaTest 中的所有异步测试(AsyncFeatureSpec、AsyncFlatSpec、AsyncFreeSpec、AsyncFunSpec、AsyncFunSuite、AsyncWordSpec)中看到相同的行为。

原因是 ScalaTest 中默认的执行上下文是串行执行上下文。您可以在这里阅读更多相关内容:https://www.scalatest.org/user_guide/async_testing https://www.scalatest.org/user_guide/async_testing。我总结了以下要点。

在 JVM 上使用 ScalaTest 的串行执行上下文将确保生成从测试主体返回的 Future[Assertion] 的同一线程也用于执行在执行测试主体时给予执行上下文的任何任务,并且不允许该线程在测试完成之前执行其他任何操作。

然而,这种线程限制策略确实意味着,当您在 JVM 上使用默认执行上下文时,您必须确保永远不会在测试主体中阻塞,等待执行上下文完成任务。如果你阻止,你的测试将永远不会完成。

解决方案 1:覆盖执行上下文

implicit override def executionContext = scala.concurrent.ExecutionContext.Implicits.global

解决方案 2:链接

class Test extends AsyncFunSuite {

  test("async test") {
    val f = Future {
      val thread = new Thread {
        override def run(): Unit = {
          println("OKAYY")
        }
      }
      thread.start()
    }

    f.map { _ =>
      assert(true)
    }
  }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么当我执行 Await.result 时,我的 Scala 异步测试永远不会完成? 的相关文章

随机推荐