gpt4 book ai didi

Scala 和 Akka - 使用 Akka Testkit 将 actor 作为系统进行测试

转载 作者:行者123 更新时间:2023-12-02 20:47:20 24 4
gpt4 key购买 nike

在我的 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]
}
}

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

最佳答案

对我来说,听起来你想要的是单独测试 Actor A 的行为。为了做到这一点,您需要能够控制 actor A 如何获取对 actor B 的引用。例如,您可以在 actor 的构造函数中提供引用:

import akka.actor.{Actor, ActorRef, Props}

class A(refToB: ActorRef) extends Actor { ... }

object A {
def props(refToB: ActorRef): Props = Props(new A(refToB))
}

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

现在您可以控制对 actor B 的引用,您可以在测试中用测试探针替换 actor 引用。

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

关于Scala 和 Akka - 使用 Akka Testkit 将 actor 作为系统进行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36633566/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com