I have an EventSourcedBehavior that will eventually get a message which leads to one last event and then stops itself. Implementing this is not the problem, but when I want to test it I get a DeadLetter Message because the EventSourcedBehaviorTestKit sends a "GetState" message right after the runCommand. Problem is: the behavior stopped itself and cannot respond anymore.
I have looked into the api docs of EventSourcedBehaviorTestKit but cannot find a suitable method to achieve my goal.
Here is a simple test that showcases my problem:
"test behavior stop" in {
sealed trait Command
case object Hi extends Command
sealed trait Event
sealed trait State
case object Empty extends State
val behavior = EventSourcedBehavior[Command, Event, State](
PersistenceId.ofUniqueId("1"),
Empty,
(_,_) => Effect.none.thenStop(),
(_,_) => Empty)
val kit = EventSourcedBehaviorTestKit[Command, Event, State](system, behavior)
kit.runCommand(Hi)
}
[2022-10-31 19:30:30,059] [INFO] [akka.actor.LocalActorRef] [SomeSpec-akka.actor.default-dispatcher-3] [akka://SomeSpec/system/test/$a] - Message [akka.persistence.typed.internal.EventSourcedBehaviorImpl$GetState] to Actor[akka://SomeSpec/system/test/$a#-553414380] was not delivered. [1] dead letters encountered. If this is not an expected behavior then Actor[akka://SomeSpec/system/test/$a#-553414380] may have terminated unexpectedly. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
- must test behavior stop *** FAILED ***
[info] java.lang.AssertionError: Timeout (3 seconds) during receiveMessage while waiting for message.
[...]
build.sbt
---------
...
lazy val akkaVersion = 2.6.19
"com.typesafe.akka" %% "akka-actor-testkit-typed" % akkaVersion % Test,
"com.typesafe.akka" %% "akka-persistence-testkit" % akkaVersion % Test,
"org.scalatest" %% "scalatest" % "3.1.4" % Test
...
How can I setup the test so that I can run this command and then expect the behavior to stop?
Stopping is not testable with the EventSourcedBehaviorTestKit
.
You can leverage the PersistentTestKit
's in-memory journal and snapshot store and test using the ActorTestKit
.
Alternatively, as of Akka 2.7.0, there's the ability to turn an EventSourcedBehavior
into one that doesn't persist but exposes events and snapshots on probes (instead of the secret GetState
command as the EventSourcedBehaviorTestkit
does) and is testable using the BehaviorTestkit
or ActorTestkit
(though the ergonomics favor the former).