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]