TestKit Example

TestKit Example

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