Akka中的TestKit.expectMsgClass

问题描述 投票:1回答:1

在下面的代码中:

TestKit probe = new TestKit(system); // line 1
ActorRef deviceActor = system.actorOf(Device.props("group", "device")); // line 2

deviceActor.tell(new DeviceManager.RequestTrackDevice("group", "device"), probe.getRef()); // line 3
probe.expectMsgClass(DeviceManager.DeviceRegistered.class); // line 4
assertEquals(deviceActor, probe.getLastSender()); // line 5

如果我注释掉第4行,则测试失败。第3行足以将消息发送给演员。那么4号线到底在做什么呢?

unit-testing akka akka-testkit
1个回答
1
投票

要了解发生了什么,让我们检查一下源代码。

以下是getLastSender()的定义,其中pTestProbe

public ActorRef getLastSender() {
  return p.lastMessage().sender();
}

lastMessageTestKit.scala中声明如下:

private[akka] var lastMessage: Message = NullMessage

lastMessage变量以两种方法之一receiveWhilereceiveOne进行突变。 expectMsgClass方法称后者:

def expectMsgClass[C](max: FiniteDuration, c: Class[C]): C = expectMsgClass_internal(max.dilated, c)

private def expectMsgClass_internal[C](max: FiniteDuration, c: Class[C]): C = {
  val o = receiveOne(max)
  // ...
}

基本上,如果你没有在测试中调用其中一个TestKit的内置断言(例如,expectMsg*方法之一),那么lastMessage将保持不变为NullMessage。如果lastMessageNullMessage,那么调用lastMessage.sender将导致异常,并且测试中的assertEquals(deviceActor, probe.getLastSender());将失败。

另一方面,如果你确实调用了内置的断言,例如expectMsgClass,那么lastMessage将被正确设置,lastMessage的发送者将正确解析。

简而言之,调用getLastSender()假定使用TestKit断言。这是在documentation(强调我的)中暗示的:

探针存储最后出列的消息的发送者(即在其接收expectMsg*之后),其可以使用getLastSender()方法检索。

© www.soinside.com 2019 - 2024. All rights reserved.