I'm writing an Actor
that should watch another Actor
; let's call the latter one the target. My Actor
should stop itself once its target is stopped. For this target I only have an ActorSelection
. To watch it, I obviously need an ActorRef
, so I figured I should send the ActorSelection
an Identify
message; when it replies back with ActorIdentity
I would have its ActorRef
. So far so good, but I can't get it to work.
Here's the spec:
// Arrange
val probe = TestProbe()
val target = TestProbe().ref
val sut = system.actorOf(MyActor.props(system.actorSelection(target.path)), "watch-target")
probe watch sut
// Act
target ! PoisonPill
// Assert
probe.expectTerminated(sut)
And the implementation (an FSM
, details skipped):
log.debug("Asking target selection {} to identify itself; messageId={}", selection.toString(), messageId)
selection ! Identify(messageId)
when(Waiting) {
case Event(ActorIdentity(`messageId`, Some(ref)), Queue(q)) =>
log.info("Received identity for remote target: {}", ref)
context.watch(ref)
goto(NextState) using TargetFound(ref)
case Event(ActorIdentity(`messageId`, None), Queue(q)) =>
log.error("Could not find requested target {}", selection.toString())
stop()
}
initialize()
Now, when I run my test, it is green because the system under test is indeed stopped. But the problem is it stops itself because it can't find its target using the aforementioned steps. The log file says:
Asking target selection ActorSelection[Anchor(akka://default/), Path(/system/testProbe-3)] to identify itself; messageId=871823258
Could not find requested target ActorSelection[Anchor(akka://default/), Path(/system/testProbe-3)]
Am I missing something obvious here? Maybe a TestProbe
should not reveal its real identity? I even tried by instantiating a dummy Actor
as target but the results are the same. Any clue?