首先,咱们须要了解如何测试发送和接受消息,包括发送而后无论的模式以及发送以后等待回复的交互式模式。
使用的是 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异步