为什么当我执行Await.result时,我的Scala异步测试从未完成? [英] Why my Scala Async test never completes when I do Await.result?

查看:269
本文介绍了为什么当我执行Await.result时,我的Scala异步测试从未完成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个简单的测试方案来显示此内容:

I have created a simple test scenario that shows this:

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)
    }
  }

}

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

When executing this, the test runs forever and never completes.

推荐答案

在ScalaTest中,所有异步测试(AsyncFeatureSpec,AsyncFlatSpec,AsyncFreeSpec,AsyncFunSpec,AsyncFunSuite,AsyncWordSpec)中都会看到相同的行为.

You will see the same behavior with all asynchronous testing in ScalaTest (AsyncFeatureSpec, AsyncFlatSpec, AsyncFreeSpec, AsyncFunSpec, AsyncFunSuite, AsyncWordSpec).

这样做的原因是ScalaTest中的默认执行上下文是串行执行上下文.您可以在此处了解更多信息: https://www.scalatest.org/user_guide/async_testing.我总结了以下要点.

The reason for this is that the default execution context in ScalaTest is serial execution context. You can read more about this here: https://www.scalatest.org/user_guide/async_testing. I have summarized the important points below.

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

Using ScalaTest's serial execution context on the JVM will ensure the same thread that produced the Future[Assertion] returned from a test body is also used to execute any tasks given to the execution context while executing the test body—and that thread will not be allowed to do anything else until the test completes.

但是,此线程限制策略的确意味着,当您在JVM上使用默认执行上下文时,必须确保不要在测试主体中阻塞,以等待执行上下文完成任务.如果您阻止,则测试将永远无法完成.

This thread confinement strategy does mean, however, that when you are using the default execution context on the JVM, you must be sure to never block in the test body waiting for a task to be completed by the execution context. If you block, your test will never complete.

解决方案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)
    }
  }

}

这篇关于为什么当我执行Await.result时,我的Scala异步测试从未完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆