2. 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
3. What is AkkaWhat 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 tolerance
Applications.
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 tolerance
Applications.
4. 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")
5. Defining an Akka actorDefining an Akka actor
package 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")
}
}
6. Creating an actorCreating an actor
package com.Testing
import akka.actor.ActorSystem
import 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.ActorSystem
import akka.actor.Props
object CreateActor extends App {
val system = ActorSystem("testing")
val actor = system.actorOf(Props[SimpleActor])
actor ! "hello"
}
7. 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.
8. 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).
9. Obtaining a Reference to an ActorObtaining 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
10. 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)
11. 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
12. Integration test with TestkitIntegration 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")
}
13. 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
14. Timing AssertionsTiming Assertions
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
}
}
}
}
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
}
}
}
}
15. 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
16. Using ProbesUsing Probes
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")
}
}
}
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")
}
}
}