如何在Akka Testkit Typed中替代Classic版本的expectMsgAnyOf与expectMsgAllOf方法?
Akka Testkit Typed 实现消息任意匹配与全匹配校验
我完全懂你碰到的这个小困扰——Akka Testkit Typed确实没有直接照搬Classic版本里的expectMsgAnyOf和expectMsgAllOf方法,但咱们用它自带的工具就能轻松实现一模一样的功能,甚至还能更灵活!下面就对着你的两个测试场景一步步来写:
1. 「回复问候语」:任意消息匹配(对应Classic的expectMsgAnyOf)
这个场景是校验Actor回复的消息是指定列表中的任意一个。在Typed里,我们可以结合TestProbe.expectMessageType和断言库来实现:
用ScalaTest匹配器的写法(推荐)
import akka.actor.typed.scaladsl.ActorTestKit import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike class GreetingActorSpec extends ActorTestKit with AnyWordSpecLike with Matchers { // 初始化你的Typed Actor private val labTestActor = spawn(YourActor()) "LabTestActor" should { "reply with either 'hi' or 'hello' when sent 'greeting'" in { labTestActor ! "greeting" // 接收String类型的回复消息 val reply = testProbe.expectMessageType[String] // 断言回复是指定选项之一 reply should be(oneOf("hi", "hello")) } } }
手动断言的写法(无需ScalaTest匹配器)
如果你的测试环境没用到ScalaTest,也可以用基础的集合判断:
val reply = testProbe.expectMessageType[String] assert(Set("hi", "hello").contains(reply), s"Unexpected reply: $reply")
2. 「回复偏好技术栈」:全消息匹配(对应Classic的expectMsgAllOf)
这个场景是校验Actor回复的消息包含所有指定内容(顺序不做要求)。我们可以先收集所有回复消息,再断言集合与目标集合相等:
用ScalaTest匹配器的写法
import akka.actor.typed.scaladsl.ActorTestKit import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpecLike class TechPreferenceActorSpec extends ActorTestKit with AnyWordSpecLike with Matchers { private val labTestActor = spawn(YourActor()) "LabTestActor" should { "reply with both 'Scala' and 'Akka' when sent 'favoriteTech'" in { labTestActor ! "favoriteTech" // 收集2条String类型的回复消息,转成集合 val replies = (1 to 2).map(_ => testProbe.expectMessageType[String]).toSet // 断言集合完全匹配目标内容 replies should equal(Set("Scala", "Akka")) } } }
用receiveN批量接收的写法
如果需要一次性接收多条消息,也可以用receiveN方法:
// 一次性接收2条消息,转成String集合 val replies = testProbe.receiveN(2).map(_.asInstanceOf[String]).toSet replies should contain allOf ("Scala", "Akka")
如果你的Actor是按固定顺序发送消息,也可以连续调用expectMessage逐个校验,但用集合判断的方式更贴合Classic版expectMsgAllOf不要求顺序的特性。
内容的提问来源于stack exchange,提问作者Vadim
相关产品推荐
相关产品推荐

