TestKit Example (Scala)

TestKit Example (Scala)

Ray Roestenburg's example code from his blog adapted to work with Akka 1.1.

  1. package unit.akka
  2.  
  3. import org.scalatest.matchers.ShouldMatchers
  4. import org.scalatest.{WordSpec, BeforeAndAfterAll}
  5. import akka.actor.Actor._
  6. import akka.util.duration._
  7. import akka.testkit.TestKit
  8. import java.util.concurrent.TimeUnit
  9. import akka.actor.{ActorRef, Actor}
  10. import util.Random
  11.  
  12. /**
  13. * a Test to show some TestKit examples
  14. */
  15.  
  16. class TestKitUsageSpec extends WordSpec with BeforeAndAfterAll with ShouldMatchers with TestKit {
  17. val system = ActorSystem()
  18. import system._
  19. val echoRef = actorOf(Props(new EchoActor))
  20. val forwardRef = actorOf(Props(new ForwardingActor(testActor)))
  21. val filterRef = actorOf(Props(new FilteringActor(testActor)))
  22. val randomHead = Random.nextInt(6)
  23. val randomTail = Random.nextInt(10)
  24. val headList = List().padTo(randomHead, "0")
  25. val tailList = List().padTo(randomTail, "1")
  26. val seqRef = actorOf(Props(new SequencingActor(testActor, headList, tailList)))
  27.  
  28. override protected def afterAll(): scala.Unit = {
  29. stopTestActor
  30. echoRef.stop()
  31. forwardRef.stop()
  32. filterRef.stop()
  33. seqRef.stop()
  34. }
  35.  
  36. "An EchoActor" should {
  37. "Respond with the same message it receives" in {
  38. within(100 millis) {
  39. echoRef ! "test"
  40. expectMsg("test")
  41. }
  42. }
  43. }
  44. "A ForwardingActor" should {
  45. "Forward a message it receives" in {
  46. within(100 millis) {
  47. forwardRef ! "test"
  48. expectMsg("test")
  49. }
  50. }
  51. }
  52. "A FilteringActor" should {
  53. "Filter all messages, except expected messagetypes it receives" in {
  54. var messages = List[String]()
  55. within(100 millis) {
  56. filterRef ! "test"
  57. expectMsg("test")
  58. filterRef ! 1
  59. expectNoMsg
  60. filterRef ! "some"
  61. filterRef ! "more"
  62. filterRef ! 1
  63. filterRef ! "text"
  64. filterRef ! 1
  65.  
  66. receiveWhile(500 millis) {
  67. case msg: String => messages = msg :: messages
  68. }
  69. }
  70. messages.length should be(3)
  71. messages.reverse should be(List("some", "more", "text"))
  72. }
  73. }
  74. "A SequencingActor" should {
  75. "receive an interesting message at some point " in {
  76. within(100 millis) {
  77. seqRef ! "something"
  78. ignoreMsg {
  79. case msg: String => msg != "something"
  80. }
  81. expectMsg("something")
  82. ignoreMsg {
  83. case msg: String => msg == "1"
  84. }
  85. expectNoMsg
  86. }
  87. }
  88. }
  89. }
  90.  
  91. /**
  92. * An Actor that echoes everything you send to it
  93. */
  94. class EchoActor extends Actor {
  95. def receive = {
  96. case msg => {
  97. self.reply(msg)
  98. }
  99. }
  100. }
  101.  
  102. /**
  103. * An Actor that forwards every message to a next Actor
  104. */
  105. class ForwardingActor(next: ActorRef) extends Actor {
  106. def receive = {
  107. case msg => {
  108. next ! msg
  109. }
  110. }
  111. }
  112.  
  113. /**
  114. * An Actor that only forwards certain messages to a next Actor
  115. */
  116. class FilteringActor(next: ActorRef) extends Actor {
  117. def receive = {
  118. case msg: String => {
  119. next ! msg
  120. }
  121. case _ => None
  122. }
  123. }
  124.  
  125. /**
  126. * An actor that sends a sequence of messages with a random head list, an interesting value and a random tail list
  127. * The idea is that you would like to test that the interesting value is received and that you cant be bothered with the rest
  128. */
  129. class SequencingActor(next: ActorRef, head: List[String], tail: List[String]) extends Actor {
  130. def receive = {
  131. case msg => {
  132. head map (next ! _)
  133. next ! msg
  134. tail map (next ! _)
  135. }
  136. }
  137. }