使用 .underlyingActor 可以监控Akka演员的状态。
在下面的示例中,使用整数计数器存在 ActorWithState 。计数器递增和递减的过程由 ActorWithStateTest 测试。增量步骤总是通过。但是,计数器的减少似乎不起作用,因为第二个断言总是失败。错误消息如下。 出了什么问题?
[此测试的错误讯息]
[info] ActorWithStateTest
[info] - should validate counter incrementation and decrementation *** FAILED ***
[info] 1 did not equal 0, Expected counter to be 0 after 'Terminated' message
[有柜台的演员]
object ActorWithState {
case class Inc;
}
class ActorWithState(snooper: ActorRef) extends Actor with ActorLogging {
var counter = 0
def receive = {
case Inc => counter += 1
case Terminated(ref) => counter -= 1
}
}
[ActorTest将测试计数器的行为]
class ActorWithStateTest extends TestKit(ActorSystem("SimpleTestSpec")) {
"Test" should {
"validate counter incrementation and decrementation" in {
val aws = TestActorRef(Props(classOf[ActorWithState], testActor), name = "aws")
val awsA: ActorWithState = aws.underlyingActor
// tell aws to increment its counter
aws ! ActorWithState.Inc
// this assert always passes
assert(awsA.counter == 1, ", Expected counter to be 1 after 'Inc' message")
// triggers a 'Terminated' message being sent to aws
val tp = TestProbe()
aws watch tp.ref
system stop tp.ref
// [EDIT] the following assert passes if some - time consuming - processing is added here
// the following assert does NOT pass, WHY?
assert(awsA.counter == 0, ", Expected counter to be 0 after 'Terminated' message")
}
}
[akka-actor:2.3.2,akka-testkit:2.3.2,scalatest:2.0]
答案 0 :(得分:3)
正如我的评论中提到的,你的问题源于停止演员异步。您的断言发生在Terminated
消息击中您正在测试的演员之前。解决此问题的一种快速而肮脏的方法是引入另一个探测器,该探测器还侦听已终止的事件并首先执行断言。这将等到第二个观察者收到终止后,这意味着你的演员也收到了已终止的事件,你可以执行你的断言。这对我有用:
val tp = TestProbe()
val tp2 = TestProbe()
aws watch tp.ref
tp2 watch tp.ref
system stop tp.ref
tp2.expectTerminated(tp.ref)
assert(awsA.counter == 0, ", Expected counter to be 0 after 'Terminated' message")