首页 > 解决方案 > 如何使用akka测试套件在scala测试中以异步方式获取未来的价值

问题描述

我正在使用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/用户指南/异步测试

为此,我需要从我选择的任何给定类扩展,AsyncWordSpec以便我可以运行异步测试并每次都获得未来的值,但我已经从TestKit类扩展,我不能从抽象类扩展,AsyncWordSpec 所以我怎么能让它工作?

标签: scalaakkascalatestakka-testkit

解决方案


一些澄清:

阻塞运行测试的单个线程直到未来完成是可以的,在测试用例中没有任何价值是异步的。测试线程与 Akka 内部的线程/调度程序是分开的,在那里阻塞是有问题的。

例如,在完成时阻塞是 TestKit 探测器所做的事情expectMessageAwait.result是一种方式,Scalatest 也有ScalaFutures它添加一个装饰器到Future被调用的.futureValueand .whenReady,这两个也阻塞测试线程,直到未来完成或达到超时。


推荐阅读