TestKit.expectMsgClass 作为
TestKit.expectMsgClass in Akka
在下面的代码中:
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 行到底在做什么?
要了解发生了什么,让我们检查一下源代码。
这里是getLastSender()
的定义,其中p
是一个TestProbe
:
public ActorRef getLastSender() {
return p.lastMessage().sender();
}
lastMessage
在TestKit.scala
中声明如下:
private[akka] var lastMessage: Message = NullMessage
lastMessage
变量在 receiveWhile
和 receiveOne
两种方法之一中发生变异。 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
的 built-in 断言之一(例如,expectMsg*
方法之一),那么 lastMessage
将保持不变为 NullMessage
。如果 lastMessage
是 NullMessage
,那么调用 lastMessage.sender
将导致异常,并且您的测试中的 assertEquals(deviceActor, probe.getLastSender());
将失败。
另一方面,如果您确实调用了 built-in 断言,例如 expectMsgClass
,那么 lastMessage
将被适当地设置,并且 lastMessage
的发送者将正确解析。
简而言之,调用 getLastSender()
假定使用 TestKit
断言。这隐含在 documentation(强调我的):
The probe stores the sender of the last dequeued message (i.e. after its expectMsg*
reception), which may be retrieved using the getLastSender()
method.
在下面的代码中:
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 行到底在做什么?
要了解发生了什么,让我们检查一下源代码。
这里是getLastSender()
的定义,其中p
是一个TestProbe
:
public ActorRef getLastSender() {
return p.lastMessage().sender();
}
lastMessage
在TestKit.scala
中声明如下:
private[akka] var lastMessage: Message = NullMessage
lastMessage
变量在 receiveWhile
和 receiveOne
两种方法之一中发生变异。 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
的 built-in 断言之一(例如,expectMsg*
方法之一),那么 lastMessage
将保持不变为 NullMessage
。如果 lastMessage
是 NullMessage
,那么调用 lastMessage.sender
将导致异常,并且您的测试中的 assertEquals(deviceActor, probe.getLastSender());
将失败。
另一方面,如果您确实调用了 built-in 断言,例如 expectMsgClass
,那么 lastMessage
将被适当地设置,并且 lastMessage
的发送者将正确解析。
简而言之,调用 getLastSender()
假定使用 TestKit
断言。这隐含在 documentation(强调我的):
The probe stores the sender of the last dequeued message (i.e. after its
expectMsg*
reception), which may be retrieved using thegetLastSender()
method.