如何在scala测试中使用akka测试套件以异步方式获得未来的值

7gcisfzg  于 2022-11-06  发布在  Scala
关注(0)|答案(2)|浏览(117)

我正在使用akka testkit和scalatests来运行我的测试,这是我的代码

class MyTest extends (ActorSystem("testsystem")) /*with AsyncWordSpec*/ with ImplicitSender with AnyWordSpecLike  with Matchers with BeforeAndAfterAll {
   "an actor test" must {
      val probe = TestProbe()
      val myActor1 = TestActorRef[MyActor]

      "send back messages " in {
        probe.send(myActor1,Found(id = "234"))
        probe.expectMsg(true)
        //i want to get the future value like this as well 
        val future = ask(myActor, Found(id = "234")).mapTo[Boolean]
        future onComplete {
            case Success(somevalue) => info("oncomplete returned result is " + somevalue)
            case Failure(ex) =>throw ex
        }
    }
}

class MyActor extends Actor {

  def receive: PartialFunction[Any, Unit] = {
    case Found(id) => 
      log.info("received message {}", id)
      sender() ! true
    case message =>
      unhandled(message)
  }
}

现在的问题是上面的代码工作正常,但未来的完整部分有时会执行,有时不会,当运行测试时,我研究了异步测试scala,并试图实现示例http://www.scalatest.org/user_guide/async_testing
因此,我需要从任何一个给定的类扩展,我选择了AsyncWordSpec,这样我就可以运行异步测试,每次都可以得到future的值,但是我已经从TestKit类扩展了,我不能从抽象类AsyncWordSpec扩展,所以我如何才能让它工作呢?

iswrvxsc

iswrvxsc1#

问题是你的future需要等待,以确保它被执行。future在异步创建的那一刻开始求值。这意味着主线程在未来完成之前不会被阻塞--它会继续运行。所以,在你的情况下有两种可能性:

1)
test start
|
|_ _ _ _ _ _ _ _
future creation  \
|                |
|                | 
|                future completed, callback executed
test end
2) 

test start
|
|_ _ _ _ _ _ _ _ _ 
future creation   \
|                 |
|                 | 
|                 |
test end          |
executor shutdown X - future termination, no callback

在第二种情况下,由于测试退出时的未来终止,回调不会运行。为了使这件事更可预测,您应该在测试结束时阻塞结果的未来。您可以使用test framework sugar或Await.result来实现这一点。

ttisahbt

ttisahbt2#

一些澄清:
阻塞运行测试的单个线程直到将来完成是好的,在异步测试用例中没有任何价值。测试线程与Akka中的线程/调度器是分开的,在那里阻塞会有问题。
例如,当您执行expectMessage时,TestKit探测器会在完成时阻塞。Await.result是单向的,Scalatest也有ScalaFutures,它向Future添加了一个装饰器,称为.futureValue.whenReady,这两个装饰器也会阻塞测试线程,直到将来完成或达到超时。

相关问题