Search code examples
scalaakkaactorakka-testkit

Test code from Akka documentation runs strangely


I am learning test methods in the Akka actor model. I tried to run some code from the Akka documentation. When I run the following code, a confusing error occurs. I'm using JDK 1.8.121, macOS, and Scala 2.12.

The code from the Akka documentation:

val probe = TestProbe()
val future = probe.ref ? "hello"
probe.expectMsg(0 millis, "hello") // TestActor runs on CallingThreadDispatcher
probe.reply("world")
assert(future.isCompleted && future.value == Some(Success("world")))

I set up the test on my own computer:

package TestKitDemo

import akka.actor.ActorSystem
import akka.actor.Status.Success
import akka.testkit.{TestKit, TestProbe}
import org.scalatest.{BeforeAndAfterAll, WordSpecLike}
import akka.pattern.ask
import akka.util.Timeout

import scala.concurrent.duration._
import scala.util.Try

class ReplyDemo extends TestKit(ActorSystem("Testsystem")) with WordSpecLike
with BeforeAndAfterAll{
//  import system.dispatcher
  override protected def afterAll(): Unit = {
    shutdown(system)
  }

  implicit val timeout = Timeout(2 seconds)
  "reply" should {
    "same" in {

      val probe = TestProbe()
      val future = probe.ref ? "hello"
      probe.expectMsg(0 millis, "hello") // TestActor runs on CallingThreadDispatcher
      probe.reply("world")


      // error
      assert(future.isCompleted && future.value == Some(Success("world")))

      // correct
//      assert(future.isCompleted && future.value.get == Try("world"))

    }
  }
}

I use two types of assert: one is the code in the Akka documentation, the other is my own equality test using Try.

I have an idea about what Try is. To my knowledge, Try is a type that can be Success or Failure.

The test error is below:

future.isCompleted was true, but Some(Success("world")) did not equal Some(Success(world))
ScalaTestFailureLocation: TestKitDemo.ReplyDemo at (ReplyDemo.scala:44)
Expected :Some(Success(world))
Actual   :future.isCompleted was true, but Some(Success("world"))

Some(Success("world")) is not equal to Some(Success(world)). What's wrong? They should be equal.


Solution

  • assert(future.isCompleted && future.value == Some(Success("world")))
    

    The reason the above assertion fails in your test is because you're trying to match on akka.actor.Status.Success instead of scala.util.Success. Replace

    import akka.actor.Status.Success
    

    with

    import scala.util.Success
    

    and your test will pass.