【问题标题】:Scala and Akka - Testing actors as a system with Akka TestkitScala and Akka - 使用 Akka Testkit 将参与者作为系统进行测试
【发布时间】:2016-04-14 20:40:37
【问题描述】:

在我的 Scala 应用程序中说我有 Actor A 和 Actor B。我想在 ScalaTest 中设计一个测试用例,允许我向 Actor A 发送消息并查看它发送给 Actor B 的消息,以查看 A 是否正确处理它的数据并发送正确的给B发消息。如何测试这个?我花了很长时间才自己完成这个……但它似乎确实有效。

class A extends Actor { ... }

class B extends Actor { ... }

class C(p: TestProbe) extends B {
  override def receive = {
    LoggingReceive {
      case x =>
        println(x.toString)
        p.ref ! x
    }
  }
}

case class MsgToB(...)

// Spec class which extends TestKit
"A" should {
  "send the right message to B" {
    val p = TestProbe()
    val a = TestActorRef[A]
    val c = TestActorRef(Props(new C(p)))

    // Assume A has a reference to C. Not shown here.
    a ! msg
    // Assert messages
    p.expectMsgType[MsgToB]
  }
}

这是最好的方法吗?有更好的做法吗?

【问题讨论】:

    标签: scala unit-testing akka akka-testkit


    【解决方案1】:

    在我看来,您想要的是单独测试演员 A 的行为。为此,您需要能够控制演员 A 获取其对演员 B 的引用的方式。例如,您可以在演员的构造函数中提供引用:

    import akka.actor.{Actor, ActorRef, Props}
    
    class A(refToB: ActorRef) extends Actor { ... }
    
    object A {
      def props(refToB: ActorRef): Props = Props(new A(refToB))
    }
    

    还有其他方法可以将actor B 的引用传递给actor A,但是使用构造函数可以说是最简单的选择。在上面的例子中,我们还提供了一个方法来为actor创建正确的Props

    现在您可以控制对参与者 B 的引用,您可以在测试中将参与者引用替换为测试探针。

    import akka.testkit.TestProbe
    
    // Initialise a test probe
    val probe = TestProbe()
    
    // Actor A with reference to actor B replaced with the test probe
    val a = system.actorOf(A.props(probe.ref))
    
    // Send a message to actor A
    a ! someMessage
    
    // Verify that the probe received a correct response from actor A
    p.expectMsgType[MsgToB]
    

    请注意,我使用来自 TestKit 的演员系统而不是使用 TestActorRef 创建了演员。这意味着actor消息处理将是异步的而不是同步的。就个人而言,我发现异步测试风格更合适,因为它更好地代表了演员在生产系统中的运行方式。 Asynchronous testing is also recommended in the official documentation.

    【讨论】:

    • 我喜欢这个。我选择了最初的实现,因为我必须做一些事情,但这听起来很有趣。目标是测试从处理 Web 请求的入口 Actor 到我们执行的整个(模拟)服务调用链的整个 Actor 系统,并验证数据输出和 Web 响应。一个挑战是获得异步行为,以便不需要对断言进行排序。如果这能解决它。
    猜你喜欢
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    • 2019-12-19
    • 2017-10-13
    • 1970-01-01
    • 2018-05-25
    • 1970-01-01
    相关资源
    最近更新 更多