This document provides an overview of unit testing Akka actors. It discusses the Akka testkit library for simplifying actor tests, how to test actor messages using expectMsg and other built-in assertions, and demonstrates testing techniques including using TestActorRef and TestProbe. It also lists some resources for further reading on testing actors and related Scala testing topics.
2. HITCHHIKER GUID TO AKKA TESTING
ABOUT ME
▸ Aprox 7 year hands on with scala & akka
▸ Part of Indeni team
▸ mailto: 123avi@gmail.com
▸ 052-3459959
3. HITCHHIKER GUID TO AKKA TESTING
WHAT WILL BE COVERED
▸ Akka basics
▸ Settings (sbt)
▸ Simple actors app
▸ Actor messages testing
▸ UnderlyingActor
▸ Supervision testing
4. HITCHHIKER GUID TO AKKA TESTING
THE ACTOR-MESSAGING CONCEPT IS NOT NEW
▸ Formalized in 1973 by Carl Hewitt and refined by Gul
Agha in mid 80s.
▸ The first major adoption is done by Ericsson in mid 80s.
▸ Invented Erlang and later open-sourced in 90s.
▸ Built a distributed, concurrent, and fault-tolerant telcom
system which has 99.9999999% uptime
5. HITCHHIKER GUID TO AKKA TESTING
WHAT IS AKKA FRAMEWORK - TACHLES
▸ Event driving, messaging
style, concurrent, fault-tolerant
▸ Provides higher abstraction for
concurrency and parallelism
▸ No shared state
▸ Messages are kept in mailbox
and processed in order
▸ Massive scalable and lighting
fast because of the small call
stack.
7. HITCHHIKER GUID TO AKKA TESTING
AKKA TESTKIT
▸ Library to simplify unit tests on actors
▸ Can be extended by your test class
▸ Inheriting from this trait enables reception of replies from
actors, which are queued by an internal actor and can be
examined using the expectMsg... methods. Assertions and
bounds concerning timing are available in the form of
within blocks.
9. HITCHHIKER GUID TO AKKA TESTING
MIXING IMPLICIT SENDER
▸ Use implicit sender to get “sender” replies
def receive {
case _ => sender ! “hi
}
class FooActorSpec extends TestKit(ActorSystem("MySpec")) with ImplicitSender
foo ! “do something”
expectMsg(“hi”)
//without implicit sender
foo tell( “do something”, self)
expectMsg(“hi”)
10. HITCHHIKER GUID TO AKKA TESTING
TESTACTORREF
▸ TestActorRef - a special reference that comes with the
Akka TestKit.
▸ TestActorRef allows interaction with internal actor if
needed via .underlyingActor
▸ obtain reference to the actor
val actorRef = TestActorRef[MyActor]
val actor = actorRef.underlyingActor
actorRef.underlyingActor.someInner
11. HITCHHIKER GUID TO AKKA TESTING
STICK TO BEHAVIOURAL TESTING
▸ Use messages.
▸ Single responsibility principle.
▸ Use probes
▸ make your tests readable and clear
13. HITCHHIKER GUID TO AKKA TESTING
USE BUILT IN ASSERTIONS
▸ Expecting messages
▸ Fishing for messages
def expectMsg[T](d: Duration, msg: T): T
def expectMsgPF[T](d: Duration) (pf: PartialFunction[Any, T]): T
def expectNoMsg(d: Duration) // blocks
def receiveN(n: Int, d: Duration): Seq[AnyRef]
def receiveWhile[T](max: Duration, idle: Duration, n: Int) (pf: PartialFunction[Any, T]): Seq[T]
def fishForMessage(max: Duration, hint: String) (pf: PartialFunction[Any, Boolean]): Any
14. HITCHHIKER GUID TO AKKA TESTING
BUILT IN ASSERTIONS
▸ Waiting
▸ Death watching
def awaitCond(p: => Boolean, max: Duration, interval: Duration)
def eventually[T](fun: => T) (implicit config: PatienceConfig): T //not part of testkit
val probe = TestProbe()
probe watch target
target ! PoisonPill
probe.expectTerminated(target)
15. HITCHHIKER GUID TO AKKA TESTING
MORE BUILT IN ASSERTIONS …
expectMsg[T](d: Duration, msg: T): T
expectMsgPF[T](d: Duration)(pf: PartialFunction[Any, T]): T
expectMsgClass[T](d: Duration, c: Class[T]): T
expectMsgType[T: Manifest](d: Duration)
expectMsgAnyOf[T](d: Duration, obj: T*): T
expectMsgAnyClassOf[T](d: Duration, obj: Class[_ <: T]*): T
expectMsgAllOf[T](d: Duration, obj: T*): Seq[T]
expectMsgAllClassOf[T](d: Duration, c: Class[_ <: T]*): Seq[T]
expectMsgAllConformingOf[T](d: Duration, c: Class[_ <: T]*): Seq[T]
expectNoMsg(d: Duration)
receiveN(n: Int, d: Duration): Seq[AnyRef]
fishForMessage(max: Duration, hint: String)(pf: PartialFunction[Any, Boolean]): Any
receiveOne(d: Duration): AnyRef
receiveWhile[T](max: Duration, idle: Duration, messages: Int)
16. HITCHHIKER GUID TO AKKA TESTING
FURTHER READING
▸ Scala test - select your flavor
▸ Testing Actor System
▸ Injecting test probe for child actors
▸ Unit testing akka actors with testkit
▸ ScalaCheck user guide
▸ ScalaCheck examples
▸ Mocks are not Stubs
▸ Akka docs - multi-node-testing