首先,咱們須要瞭解如何測試發送和接受消息,包括髮送而後無論的模式以及發送以後等待回覆的交互式模式。
使用的是 Scala 的測試框架 [ScalaTest]http://www.scalatest.org/。這個框架被設計成可讀性性很高。
使用這個工具能夠生成可讀性很強的測試報告。固然 Akka 也爲咱們提供了測試工具 akka-test,若是沒有這個工具,
咱們將面臨相比與正常對象更加困難的測試環境。主要有下面四個緣由:多線程
下面主要從兩個方面演示如何利用 akka-testkit + ScalaTest 做測試:併發
安裝 jdk + sbt + scala, build.sbt 中加入以下內容:框架
name := "testdriven" #名字隨意取,項目名稱 version := "0.1-SNAPSHOT" organization := "com.manning" #公司域名倒過來寫,最後能夠加入部門簡稱 scalaVersion := "2.11.7" libraryDependencies ++= { val akkaVersion = "2.3.12" Seq( "com.typesafe.akka" %% "akka-actor" % akkaVersion, #注意兩個 %% 號的用法基本類 "com.typesafe.akka" %% "akka-slf4j" % akkaVersion, #日誌類 "com.typesafe.akka" %% "akka-testkit" % akkaVersion % "test", #最後一個 %指定使用範圍 "org.scalatest" %% "scalatest" % "2.2.4" % "test" ) }
package packagename import org.scalatest.WordSpecLike import org.scalatest.MustMatchers import akka.testkit.{ TestActorRef, TestKit } import akka.actor._ package silenttest { class SilentActorTest extends TestKit(ActorSystem("testsystem")) with WordSpecLike with MustMatchers with StopSystemAfterAll { "A Silent Actor" must { "change internal state when it receives a message, single" in { import SilentActor._ // 利用TestActorRef 直接生成能夠訪問實際 Actor 對象的 Actor val silentActor = TestActorRef[SilentActor] silentActor ! SilentMessage("whisper") // 靜態的測試方法,直接訪問actor的內部對象 silentActor.underlyingActor.state must (contain("whisper")) } //<end id="ch02-silentactor-test02"/> } } object SilentActor { case class SilentMessage(data: String) case class GetState(receiver: ActorRef) } class SilentActor extends Actor { import SilentActor._ var internalState = Vector[String]() def receive = { case SilentMessage(data) => internalState = internalState :+ data } def state = internalState } } //通用類,目的是及時關閉全部Actor package common { import akka.testkit.TestKit import org.scalatest.{Suite, BeforeAndAfterAll} trait StopSystemAfterAll extends BeforeAndAfterAll{ //注意這種混入手法 this: TestKit with Suite => override protected def afterAll(): Unit = { super.afterAll() system.shutdown() } } }
package silentactor03 { class SilentActorTest extends TestKit(ActorSystem("testsystem")) with WordSpecLike with MustMatchers with StopSystemAfterAll { "A Silent Actor" must { "change internal state when it receives a message, multi" in { import SilentActor._ val silentActor = system.actorOf(Props[SilentActor], "s3") silentActor ! SilentMessage("whisper1") silentActor ! SilentMessage("whisper2") //經過發送消息獲取內部狀態 silentActor ! GetState(testActor) expectMsg(Vector("whisper1", "whisper2")) } } } object SilentActor { case class SilentMessage(data: String) case class GetState(receiver: ActorRef) } class SilentActor extends Actor { import SilentActor._ var internalState = Vector[String]() def receive = { case SilentMessage(data) => internalState = internalState :+ data case GetState(receiver) => receiver ! internalState } } }
scala in action異步