Testing Finite State Machines with Akka in Java

Last week, I built my first Finite State Machine in Akka with Java. I’ve done it before with Scala, and built/tested “plain ol'” actor systems in Akka with Java, but this was the first time I used Akka in Java for FSMs, and the first Akka project in the past ~2 yrs. The API has been updated, but not all of the docs had been updated. Thus, I had a heck of a time figuring out how to set up my test kit– most people are  using Scala with Akka, which means the most accessible code samples are in Scala. This doesn’t help when the Java docs are wrong too 🙁

Here’s the Java API:
https://doc.akka.io/japi/akka/current/akka/testkit/TestFSMRef.html

The (Scala) example in that doc shows you can create a TestFSMRef directly with new(). Apparently you can do that with Scala, but in Java you need to call create().

Here’s an example. I have 2 FSMs defined elsewhere, YahtzeeFSM and PlayerFSM.


private void setUpTheGameFSM() {
   // Create a Game 
   final Props props = Props.create(YahtzeeFsm.class, 2, 3);
   TestActorRef gameRef = TestFSMRef.create(system, props, "TheGame");
   ActorRef game = gameRef.underlyingActor();

   // Create a Player to send messages to the Game
   final Props playerProps = Props.create(PlayerFsm.class, gameRef, null, "Player1");
   TestActorRef playerActorRef = TestFSMRef.create(system, playerProps, "ThePlayer");
   ActorRef player = playerActorRef.underlyingActor();

}

There’s another weird thing. TestFSMRef.create() doesn’t return an instance of TestFSMRef; it returns an instance of TestActorRef. This makes it difficult when you want to use the TestFSMRef methods such as setState() (super useful when testing an FSM).

No big deal: clearly gameRef is actually a TestFSMRef, since it was created with TestFSMRef, right? Surely we can just cast it to a TestFSMRef. Oddly, this worked for a little bit, but then stopped working. I’m not quite sure why sometimes I can cast the ref to a TestFSMRef and sometimes I can’t.

Here’s the full gist:

[gotta enter]

Leave a Reply

Your email address will not be published. Required fields are marked *