'Akka Typed - How to sent Terminated message to BehaviorTestKit
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?
Solution 1:[1]
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))
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
