akkaakka-persistenceakka-testkit

Testing stop behavior of an EventSourcedBehavior in akka


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?


Solution

  • 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).