score:10

Accepted answer

Okay, I figured it out. Make sure you are using the correct version of akka-testkit. In Play 2.2.0 I was trying to use akka 2.2.M3. Obviously, that doesn't work. I had to put the correct dependencies in my Build.scala, which ended up being this:

"com.typesafe.akka" %% "akka-testkit" % "2.2.0" % "test"

My actual test code looks like this:

package test

import org.specs2.mutable._
import controllers.Scanner
import java.util.UUID
import org.joda.time.DateTime
import akka.testkit.TestActorRef
import play.api.Logger
import models.PSqlEnum
import akka.actor.ActorSystem
import com.typesafe.config.ConfigFactory
import scala.concurrent.ExecutionContext.Implicits.global

class ScannerTest extends Specification {
  val appId = UUID.randomUUID()
  val app = models.App(appId, "TestApp", "TestServer", "TestComponent", "Test Description", DateTime.now(),
                       DateTime.now(), true, 3, 60, PSqlEnum("scanType", "mandatory"), "http://localhost")
  val rules = <Rule name="DivisionDataIsAvailable" elementsToCheck="DivisionDataIsAvailable"
                    ruleType="is, true, yellow" />
              <Rule name="DivisionDataLoadIsHealthy" elementsToCheck="DivisionDataLoadIsHealthy"
                    ruleType="is, true, red" />;


  "Scanner" should {
    "test something" in {
      implicit val actorSystem = ActorSystem("testActorSystem", ConfigFactory.load())
      val scanner = TestActorRef(new Scanner(app, rules)).underlyingActor
      val response = scanner.getResponseFromWebService
      response onSuccess {
        case result => Logger.warn(result.toString)
      }
      response onFailure {
        case error => Logger.warn(error.toString)
      }
      1 === 1
    }
  }
}

Obviously again, this test isn't really doing anything. The actual test being evaluated is 1 === 1. It does print out to the log now though which means I can go back and verify datatypes and the payload of the response, and then build some actual Unit Tests. I hope someone finds this useful. Those error messages in the original question are caused by the akka-testkit dependency not being the same version as Akka though, which might be useful for someone.

score:0

I'm not using spec2 or Mockito but here is what I'm doing to unit test Akka actors in Play 2.2.1:

import org.specs2.mutable.Specification
import scala.concurrent.duration._
import org.scalatest.concurrent._
import akka.testkit._
import org.scalatest.matchers.ShouldMatchers
import org.scalatest.{FlatSpec, BeforeAndAfterAll}
import akka.actor.{Props, ActorSystem}
import akka.pattern.ask
import akka.util.Timeout
import scala.util.{Failure, Success}
import model.BlacklistEntry
import scala.concurrent.{Future, Promise, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import play.api.test.FakeApplication
import model.BlacklistEntryImpl


class LicenceBlackListSpec(_system: ActorSystem) extends TestKit(_system) with ImplicitSender with ShouldMatchers with FlatSpec with BeforeAndAfterAll {
  play.api.Play.start(FakeApplication())

  import akka.testkit.TestKit._
  def this() = this( ActorSystem("LicenceBlackListSpec") )

  override def afterAll: Unit = {
    system.shutdown()
    system.awaitTermination(10.seconds)
  }

  implicit val timeout = Timeout(10 seconds)
  val blacklistRef = TestActorRef(Props[LicenceBlackList])

  "An LicenceBlackList Actor" should "be able to create a new blacklist entry" in {
    blacklistRef ! CreateEntry(BlacklistEntryImpl("NEW_KEY",1000,"Test creation"))

    val expected: BlacklistEntry = BlacklistEntryImpl("NEW_KEY", 1000 ,"Test creation")
    expectMsg( expected )
  }
}

You'll need to include the scalatest lib as a dependency as well akka test kit:

"org.scalatest" % "scalatest_2.10" % "1.9.1"

Hope this will help.

score:0

I don't use ActorSystem("testActorSystem" ) , I have tryed to allow play framework to use it's usual akka plugin. This approach has folowing benefits: I can use play.api.libs.concurrent.Akka.system in all code, I can have extra config options that understand booth play and akka code parts .

  class BaseActorTester (_app: Application) extends akka.testkit.TestKit(play.api.libs.concurrent.Akka.system(_app)) with FunSuiteLike with BeforeAndAfterAll {

   def this() = this(FakeApplication(additionalConfiguration=Map("currency.db"->"airando-test")))
   implicit val app: Application = _app
   implicit val ec = play.api.libs.concurrent.Akka.system.dispatcher

   override def beforeAll {
     Play.start(app)
   }
   // play plugin do it itself ??
   //override def afterAll {
   //  akka.testkit.TestKit.shutdownActorSystem(system)
   //}
   ...
  }

Related Query

More Query from same tag