Search code examples
akkaakka-testkit

In akka testkit,why use a event rather then a normal method get the actor state?


In book of akka in actor's chapter three. It use a message event to test silent actor's state.

The actor as this:

object SilentActorProtocol {
 case class SilentMessage(data: String)
 case class GetState(receiver: ActorRef)
}
class SilentActor extends Actor {
 import SilentActorProtocol._
 var internalState = Vector[String]()
 def receive = {
   case SilentMessage(data) =>
     internalState = internalState :+ data
     case GetState(receiver) => receiver ! internalState
   }
}

Test code as this:

"change internal state when it receives a message, multi" in {
 import SilentActorProtocol._
 val silentActor = system.actorOf(Props[SilentActor], "s3")
 silentActor ! SilentMessage("whisper1")
 silentActor ! SilentMessage("whisper2")
 silentActor ! GetState(testActor)
 expectMsg(Vector("whisper1", "whisper2"))
}

Inner the test code why use GetState get result of above SilentMessage event.
Why not use slientActor.internalState get the result straightly?

Update

Some friends seems mislead my problem.For detail, The books said

use the internalState variable will encounter concurrency problem, so there should use a GetState event tell actor to get the actor's inner state rather then use internalState straightly.

I don't know why it should encounter concurrency problem and why use GetState can fix the problem

Explain

slientActor.internalState can't get inner variable straightly , instand, use silentActor.underlyingActor.internalState can get it.So sorry for the terrible question.


Solution

  • If I understand your question correctly, the answer is that the silentActor in the test code is not the actor, it is the ActorRef instance, therefore it does not have the internalState var to be referenced.

    If you want to write unit tests for specific variables and methods on the ActorRef, you need to use the underlyingActor technique as described (with its caveats) in the documentation. (see section on TestActorRef.