scala - 测试依赖于 future 的 AKKA Actor

标签 scala testing concurrency akka future

<分区>

我正在尝试为依赖于 Future 的 actor 编写一个简单的测试。这是几乎不言自明的代码

import akka.actor.{ Actor, ActorSystem, Props }
import akka.testkit.{ ImplicitSender, TestKit }
import org.scalatest.{ BeforeAndAfterAll, WordSpecLike }

import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

trait Provider {def get(s: String): Future[String] }

class MyActor(provider: Provider) extends Actor {
  override def receive: Receive = {
    case s: String ⇒
      provider.get(s) map { result: String ⇒
        sender() ! result
      }
  }
}

class FutureTest
  extends TestKit(ActorSystem("Test"))
    with ImplicitSender
    with WordSpecLike
    with BeforeAndAfterAll {

  "MyActor" must {
    "wait for the future" in {
      val myref = system.actorOf(Props(
        new MyActor((s) ⇒ Future { s })
      ))

      myref ! "hello world"

      expectMsg("hello world")
    }
  }
}

Expect msg 不会等待 future 完成并失败并显示以下消息:

断言失败:WAITING hello world 时 expectMsg 超时(3 秒) java.lang.AssertionError: assertion failed: expectMsg 等待 hello world 期间超时(3 秒)

在我的案例中测试这种行为的最佳实践是什么?

谢谢!

最佳答案

您永远不应该在传递给 future 的回调中关闭 sender()。请参阅此 SO 问题以了解为什么以及如何修复:

sender inside a future

关于scala - 测试依赖于 future 的 AKKA Actor ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46481769/

相关文章:

java - Scala:如何使用 Java 回调 API

除列表之外的序列上的 Scala 模式匹配

unit-testing - 单元测试对象转换器

java - 可靠地跟踪 Hibernate 所做的更改

scala - 将 float 转换为 Big Endian

scala - Spark : How do I query an array in a column?

Django - 测试不同的视觉 block

java - 如何创建一个为测试脚本传递参数的 webdriver 函数?

android - Dalvik VM 和 Java 内存模型(Android 上的并发编程)

java - java的AtomicBitSet实现