0

I'm using Akka 2.4.2 with TestKit and Scalatest for writing and testing actors. It looks like there is a race condition whenever I'm inspecting some mutable state encapsulated by my actor. I have a really simple actor that saves some state in a remote database:

class MyActor(dao: MyDao) extends Actor {
  var state: String = ""
  def receive = {
    case Set(str) => 
      state = str
      dao.save(state)
  }
}

The DAO method has the type signature dao.save(s:String): Future[String]. The call to the database is asynchronous and is made after setting state = str, so nothing would appear to be blocking the assignment of this string. The actor is accompanied by a unit test:

it should "set mutable state" in {
  val ref = TestActorRef(new MyActor(new MockDao))
  ref ! Set("foo")
  ref.underlyingActor.state shouldBe "foo"
}

If I run this test individually it will pass reliably. However, when I run all my actor tests (I have a dozen different actors), this test case will pass/fail non-deterministically. So there appears to be some kind of race occurring. I'm using the default Akka configurations. Any thoughts from the Akka community on what could be going wrong?

nmurthy
  • 1,337
  • 1
  • 12
  • 24
  • Should you be inspecting the private state of the actor? Why not assert externally visible behaviour (such as that your `MockDao.save` gets called with the proper parameter). – Thilo Sep 18 '16 at 05:12
  • 3
    Also, isn't there a race condition? I thought messages are delivered asynchonously, so doesn't it take some time before the state can be checked? – Thilo Sep 18 '16 at 05:14
  • 1
    Doesn't `TestActorRef` execute messages synchronously? see: http://doc.akka.io/docs/akka/current/scala/testing.html#Synchronous_Unit_Testing_with_TestActorRef – nmurthy Sep 18 '16 at 06:09
  • 1
    Is `dao` relevant? If you remove `dao.save(state)`, does the problem persist? I'm wondering if the test might be failing as a result of the actor crashing. – Chris Martin Sep 18 '16 at 06:43
  • @nmurthy: True, the `TestActorRef` dispatches synchronously. I guess that's a reason not to use it... – Thilo Sep 18 '16 at 07:18

0 Answers0