Akka(Scala)-使用参数iwth TestKit测试消息



在我的应用程序中,我有一个CartActor管理购物车,OrderManager负责监督整个购物过程:

object CartActor {
sealed trait Command
case class AddItem(item: Any)        extends Command
case class RemoveItem(item: Any)     extends Command
case object ExpireCart               extends Command
case object StartCheckout            extends Command
case object ConfirmCheckoutCancelled extends Command
case object ConfirmCheckoutClosed    extends Command
case object GetItems                 extends Command // command made to make testing easier
sealed trait Event
case class CheckoutStarted(checkoutRef: ActorRef) extends Event
def props() = Props(new CartActor())
}

object OrderManager {
sealed trait Command
case class AddItem(id: String)                                               extends Command
case class RemoveItem(id: String)                                            extends Command
case class SelectDeliveryAndPaymentMethod(delivery: String, payment: String) extends Command
case object Buy                                                              extends Command
case object Pay                                                              extends Command
case class ConfirmCheckoutStarted(checkoutRef: ActorRef)                     extends Command
case class ConfirmPaymentStarted(paymentRef: ActorRef)                       extends Command
case object ConfirmPaymentReceived                                           extends Command
sealed trait Ack
case object Done extends Ack //trivial ACK
}

OrderManager从CartActor接收OrderManager.ConfirmCheckoutStarted(checkoutRef: ActorRef)。我必须编写单元测试来检查这一点。我想做:

it should "start checkout" in {
val cart = TestActorRef[CartActor]
cart ! AddItem("Item")
cart ! StartCheckout
expectMsg(OrderManager.ConfirmCheckoutStarted)
}

但是我得到一个错误:assertion failed: expected ConfirmCheckoutStarted, found ConfirmCheckoutStarted(Actor[akka://CartTest/user/$$d/checkout#-1922766677])。我发现问题在于副题中有一个参数。我该如何测试?我不在乎里面的actorRef,我只想要ConfirmCheckoutStarted

我不知道巡回演出演员在回发什么消息。所以我创建了这个CartActor,发送消息OrderManager.ConfirmCheckoutStarted(self)

class CartActor extends Actor {
import CartActor._
override def receive: PartialFunction[Any, Unit] = {
case AddItem(item) => sender ! s"item $item added."
case StartCheckout => sender ! OrderManager.ConfirmCheckoutStarted(self)
case msg => println(s"I cannot understand ${msg.toString}")
}
}

然后我执行这个测试,检查演员参考:

import akka.actor.ActorSystem
import akka.testkit.{ImplicitSender, TestActorRef, TestKit}
import org.scalatest.BeforeAndAfterAll
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike
class CartActorDemoSpec extends TestKit(ActorSystem("CartActorDemoSpec"))
with ImplicitSender
with AnyWordSpecLike
with Matchers
with BeforeAndAfterAll {
override def afterAll(): Unit = {
TestKit.shutdownActorSystem(system)
}
import CartActorDemo._
"The ActorsIntro actor" should {
"send back hi replay" in {
import CartActorDemo.CartActor._
val cart = TestActorRef[CartActor]
val item = "MyItem"
cart ! AddItem(item)
expectMsg(s"item $item added.")
cart ! StartCheckout
expectMsg(OrderManager.ConfirmCheckoutStarted(cart))
}
}
}

如果您在case StartCheckout上有其他类型的消息发送,您可以相应地进行更改。

最新更新