Reputation: 3944
I'm trying to unit test my actor's handling of a "Terminated" message for a child actor. The code under test is something like this:
case Terminated(terminatedActor) =>
val actorName = terminatedActor.path.name
if (actorName.startsWith("ChildActor")) {
doSomething()
}
Behaviors.same
In my unit test, I'm trying to do something like this:
val testInbox = TestInbox[ParentActor.Request](name = "ChildActor1")
val testKit = BehaviorTestKit(ParentActor())
testKit.run(Terminated(testInbox.ref))
assert( *** that doSomething() happened *** )
The unit test code doesn't compile. I get this error in the call to testKit.run():
type mismatch; found : akka.actor.typed.Terminated required: ParentActor.Request
I assume that this is because the Terminated message does not inherit from my ParentActor.Request trait.
Based on a below comment, I changed the unit test to:
val testInbox = TestInbox[ParentActor.Request](name = "ChildActor1")
val testKit = BehaviorTestKit(ParentActor())
testKit.signal(Terminated(testInbox.ref))
assert( *** that doSomething() happened *** )
This now compiles, but the call to testKit.signal() now throws a DeathPactException, which the docs say means that the actor is not handling the Terminated message, even though my production code definitely does handle it.
Any idea what is wrong?
Upvotes: 0
Views: 368
Reputation: 20541
Are you sure that your production code definitely handles the Terminated
signal?
Signals are not, from the perspective of a typed Behavior
, messages. They are processed by the signal handler installed by receiveSignal
. That signal handler takes not just the signal but the ActorContext
as well, wrapped up in a tuple. If the response to a Terminated
signal doesn't require the context, you still have to match against it:
// inside a .receiveSignal...
case (_, Terminated(terminatedActor)) =>
val actorName = terminatedActor.path.name
if (actorName.startsWith("ChildActor")) {
doSomething()
}
Behaviors.same
Note that Akka's test suite includes this test which exercises handling the Terminated
signal when sent via testKit.signal
:
val other = TestInbox[String]()
val testkit = BehaviorTestKit[Parent.Command](Parent.init)
noException should be thrownBy {
testkit.signal(Terminated(other.ref))
}
Upvotes: 2