[英]Scala and Akka - Testing actors as a system with Akka Testkit
在我的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]
}
}
這是最好的方法嗎? 有更好的做法嗎?
對我而言,聽起來你想要的是孤立地測試演員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))
}
有其他方法可以將對actor B的引用傳遞給actor A,但使用構造函數可以說是最簡單的選擇。 在上面的示例中,我們還提供了一種為actor創建正確Props
的方法。
現在您可以控制對actor B的引用,您可以在測試中將actor引用替換為test probe。
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系統創建了actor,而不是使用TestActorRef
。 這意味着actor消息處理將是異步的而不是同步的。 就個人而言,我發現異步測試風格更合適,因為它更好地代表了演員在生產系統中的運行方式。 官方文檔中也建議進行異步測試 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.