Testing akka-actors
Click here to load reader
-
Upload
knoldus-software-llp -
Category
Technology
-
view
1.754 -
download
0
description
Transcript of Testing akka-actors
Testing Akka ActorsTesting Akka Actors
Piyush MishraSoftware Consultant
Knoldus Software LLP
Piyush MishraSoftware Consultant
Knoldus Software LLP
Topics CoveredTopics Covered
Basics of Akka
Settings in build.sbt
Defining an of Akka Actor
Creation of Akka Actor
ActorRef
Testing Akka Actors
Integration testing using testkit
Basics of Akka
Settings in build.sbt
Defining an of Akka Actor
Creation of Akka Actor
ActorRef
Testing Akka Actors
Integration testing using testkit
What is Akka What is Akka
Akka is framework for writing event driving, concurrent, fault-tolerant and scalable application.
a) It uses actor model to build concurrent, fault-tolerant and scalable application.
b) Actors are the higher abstraction for concurrency and parallelism.
c) They are very lightweight event-driven processes (approximately 2.7 million actors per GB RAM).
d) Akka provides supervisor stategy to build fault toleranceApplications.
Akka is framework for writing event driving, concurrent, fault-tolerant and scalable application.
a) It uses actor model to build concurrent, fault-tolerant and scalable application.
b) Actors are the higher abstraction for concurrency and parallelism.
c) They are very lightweight event-driven processes (approximately 2.7 million actors per GB RAM).
d) Akka provides supervisor stategy to build fault toleranceApplications.
Settings in build.sbtSettings in build.sbt
In order to test Akka actors we need to add following two dependencies in build.scala or build.sbt
libraryDependencies ++= Seq( "com.typesafe.akka" % "akka-actor" % "2.0.5", "com.typesafe.akka" % "akka-testkit" % "2.0.5")
In order to test Akka actors we need to add following two dependencies in build.scala or build.sbt
libraryDependencies ++= Seq( "com.typesafe.akka" % "akka-actor" % "2.0.5", "com.typesafe.akka" % "akka-testkit" % "2.0.5")
Defining an Akka actorDefining an Akka actorpackage com.Testing
import akka.actor.Actor
class SimpleActor extends Actor {
def receive = { case msg: String => case _ => println("Got other than string") }
}
package com.Testing
import akka.actor.Actor
class SimpleActor extends Actor {
def receive = { case msg: String => case _ => println("Got other than string") }
}
Creating an actorCreating an actor
package com.Testing
import akka.actor.ActorSystemimport akka.actor.Props
object CreateActor extends App {
val system = ActorSystem("testing") val actor = system.actorOf(Props[SimpleActor]) actor ! "hello"}
package com.Testing
import akka.actor.ActorSystemimport akka.actor.Props
object CreateActor extends App {
val system = ActorSystem("testing") val actor = system.actorOf(Props[SimpleActor]) actor ! "hello"}
What is ActorRefWhat is ActorRef
ActorRef is the Immutable and serializable handle to an actor which may or may not reside on the local host or inside the same ActorSystem .
We can not call methods on actorRef.
ActorRef is the Immutable and serializable handle to an actor which may or may not reside on the local host or inside the same ActorSystem .
We can not call methods on actorRef.
Testing with TestActorRefTesting with TestActorRef
This special type of reference is designed specifically for test purposes and allows access to the actor in two ways: either by obtaining a reference to the underlying actor instance, or by invoking or querying the actor's behaviour (receive).
This special type of reference is designed specifically for test purposes and allows access to the actor in two ways: either by obtaining a reference to the underlying actor instance, or by invoking or querying the actor's behaviour (receive).
Obtaining a Reference to an Actor Obtaining a Reference to an Actor
import akka.testkit.TestActorRef val actorRef = TestActorRef[MyActor] val actor = actorRef.underlyingActor
import akka.testkit.TestActorRef val actorRef = TestActorRef[MyActor] val actor = actorRef.underlyingActor
Testing the Actor's BehaviorTesting the Actor's Behavior
implicit val timeout = Timeout(5 seconds)implicit val system = ActorSystem("Unit")val actorRef = TestActorRef(new SimpleActor)
val result = Await.result((actorRef ? 42), 5 seconds).asInstanceOf[Int] result must be(42)
implicit val timeout = Timeout(5 seconds)implicit val system = ActorSystem("Unit")val actorRef = TestActorRef(new SimpleActor)
val result = Await.result((actorRef ? 42), 5 seconds).asInstanceOf[Int] result must be(42)
Integration test with TestkitIntegration test with Testkit
Testkit is used for integration testing of an actor. This toolkit provider a ImplicitSender which is actually a test actor which dispatches messages to actors under test.
Continued
Testkit is used for integration testing of an actor. This toolkit provider a ImplicitSender which is actually a test actor which dispatches messages to actors under test.
Continued
Integration test with Testkit Integration test with Testkit class MySpec(_system: ActorSystem) extends TestKit(_system) with ImplicitSender with WordSpec with MustMatchers with BeforeAndAfterAll {
def this() = this(ActorSystem("MySpec"))
import MySpec._
override def afterAll { system.shutdown() }
"An Echo actor" must {
"send back messages unchanged" in { val echo = system.actorOf(Props[EchoActor]) echo ! "hello world" expectMsg("hello world") }
class MySpec(_system: ActorSystem) extends TestKit(_system) with ImplicitSender with WordSpec with MustMatchers with BeforeAndAfterAll {
def this() = this(ActorSystem("MySpec"))
import MySpec._
override def afterAll { system.shutdown() }
"An Echo actor" must {
"send back messages unchanged" in { val echo = system.actorOf(Props[EchoActor]) echo ! "hello world" expectMsg("hello world") }
Timing AssertionsTiming Assertions
Timing: certain events must not happen immediately (like a timer), others need to happen before a deadline.
The block given to within must complete after a Duration which is between min and max, where the former defaults to zero. The deadline calculated by adding the max parameter to the block's start time is implicitly available within the block to all examination methods
Timing: certain events must not happen immediately (like a timer), others need to happen before a deadline.
The block given to within must complete after a Duration which is between min and max, where the former defaults to zero. The deadline calculated by adding the max parameter to the block's start time is implicitly available within the block to all examination methods
Timing AssertionsTiming Assertionsclass Timing(_system: ActorSystem) extends TestKit(_system) with ImplicitSender with MustMatchers with WordSpec { def this() = this(ActorSystem("MySpec"))
import MySpec._
"An simple actor" must {
"send reply within 2 seconds" in { val worker = system.actorOf(Props[SimpleActor]) within(200 millis) { worker ! 4 expectMsg(4) expectNoMsg // will block for the rest of the 200ms Thread.sleep(300) // will NOT make this block fail } } }}
class Timing(_system: ActorSystem) extends TestKit(_system) with ImplicitSender with MustMatchers with WordSpec { def this() = this(ActorSystem("MySpec"))
import MySpec._
"An simple actor" must {
"send reply within 2 seconds" in { val worker = system.actorOf(Props[SimpleActor]) within(200 millis) { worker ! 4 expectMsg(4) expectNoMsg // will block for the rest of the 200ms Thread.sleep(300) // will NOT make this block fail } } }}
Using ProbesUsing Probes
When the actors under test are supposed to send various messages to different destinations. approach is to use it for creation of simple probe actors to be inserted in the message flows. To make this more powerful and convenient, there is a concrete implementation called TestProbe.
The functionality is best explained using a small example
When the actors under test are supposed to send various messages to different destinations. approach is to use it for creation of simple probe actors to be inserted in the message flows. To make this more powerful and convenient, there is a concrete implementation called TestProbe.
The functionality is best explained using a small example
Using ProbesUsing Probesclass Probe(_system: ActorSystem) extends TestKit(_system) with ImplicitSender with WordSpec with MustMatchers with BeforeAndAfterAll {
def this() = this(ActorSystem("MySpec"))
import MySpec._
override def afterAll { system.shutdown() }
"An DoubleEcho actor" must {
"send reply both probes" in { val probe1 = TestProbe() val probe2 = TestProbe() val actor = system.actorOf(Props[MyDoubleEcho]) actor ! (probe1.ref, probe2.ref) actor ! "hello" probe1.expectMsg(500 millis, "hello") probe2.expectMsg(500 millis, "hello") } }}
class Probe(_system: ActorSystem) extends TestKit(_system) with ImplicitSender with WordSpec with MustMatchers with BeforeAndAfterAll {
def this() = this(ActorSystem("MySpec"))
import MySpec._
override def afterAll { system.shutdown() }
"An DoubleEcho actor" must {
"send reply both probes" in { val probe1 = TestProbe() val probe2 = TestProbe() val actor = system.actorOf(Props[MyDoubleEcho]) actor ! (probe1.ref, probe2.ref) actor ! "hello" probe1.expectMsg(500 millis, "hello") probe2.expectMsg(500 millis, "hello") } }}
ThanksThanks