add docs for ExtractRoute, see #2337

This commit is contained in:
Roland 2012-07-25 20:48:32 +02:00
parent b2ce64fb6f
commit faae09ab4e
4 changed files with 74 additions and 9 deletions

View file

@ -0,0 +1,27 @@
/**
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
*/
package akka.routing;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.routing.RoundRobinRouter;
import akka.testkit.ExtractRoute;
public class CustomRouteTest {
static private ActorSystem system;
// only to test compilability
public void testRoute() {
final ActorRef ref = system.actorOf(new Props().withRouter(new RoundRobinRouter(1)));
final scala.Function1<scala.Tuple2<ActorRef, Object>, scala.collection.Iterable<Destination>> route = ExtractRoute.apply(ref);
route.apply(null);
}
}

View file

@ -4,33 +4,45 @@
package akka.routing package akka.routing
import akka.testkit.AkkaSpec import akka.testkit.AkkaSpec
import akka.actor.Props
import akka.actor.OneForOneStrategy
import akka.actor.SupervisorStrategy
import akka.dispatch.Dispatchers
import akka.testkit.ExtractRoute
@org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) @org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner])
class CustomRouteSpec extends AkkaSpec { class CustomRouteSpec extends AkkaSpec {
class MyRouter extends RouterConfig { //#custom-router
import akka.actor.{ ActorRef, Props, SupervisorStrategy }
import akka.dispatch.Dispatchers
class MyRouter(target: ActorRef) extends RouterConfig {
override def createRoute(p: Props, prov: RouteeProvider): Route = { override def createRoute(p: Props, prov: RouteeProvider): Route = {
prov.createAndRegisterRoutees(p, 1, Nil) prov.createAndRegisterRoutees(p, 1, Nil)
{ {
case (sender, message) toAll(sender, prov.routees) case (sender, message: String) Seq(Destination(sender, target))
case (sender, message) toAll(sender, prov.routees)
} }
} }
override def supervisorStrategy = SupervisorStrategy.defaultStrategy override def supervisorStrategy = SupervisorStrategy.defaultStrategy
override def routerDispatcher = Dispatchers.DefaultDispatcherId override def routerDispatcher = Dispatchers.DefaultDispatcherId
} }
//#custom-router
"A custom RouterConfig" must { "A custom RouterConfig" must {
"be testable" in { "be testable" in {
val router = system.actorOf(Props.empty.withRouter(new MyRouter)) //#test-route
import akka.pattern.ask
import akka.testkit.ExtractRoute
import scala.concurrent.Await
import scala.concurrent.util.duration._
val target = system.actorOf(Props.empty)
val router = system.actorOf(Props.empty.withRouter(new MyRouter(target)))
val route = ExtractRoute(router) val route = ExtractRoute(router)
route(testActor -> "hallo").size must be(1) val r = Await.result(router.ask(CurrentRoutees)(1 second).mapTo[RouterRoutees], 1 second)
r.routees.size must be(1)
route(testActor -> "hallo") must be(Seq(Destination(testActor, target)))
route(testActor -> 12) must be(Seq(Destination(testActor, r.routees.head)))
//#test-route
} }
} }

View file

@ -707,3 +707,17 @@ Some `Specs2 <http://specs2.org>`_ users have contributed examples of how to wor
* Specifications are by default executed concurrently, which requires some care * Specifications are by default executed concurrently, which requires some care
when writing the tests or alternatively the ``sequential`` keyword. when writing the tests or alternatively the ``sequential`` keyword.
Testing Custom Router Logic
===========================
Given the following custom (dummy) router:
.. includecode:: ../../akka-actor-tests/src/test/scala/akka/routing/CustomRouteSpec.scala#custom-router
This might be tested by dispatching messages and asserting their reception at
the right destinations, but that can be inconvenient. Therefore exists the
:obj:`ExtractRoute` extractor, which can be used like so:
.. includecode:: ../../akka-actor-tests/src/test/scala/akka/routing/CustomRouteSpec.scala#test-route

View file

@ -8,6 +8,18 @@ import scala.annotation.tailrec
import akka.actor.{ UnstartedCell, ActorRef } import akka.actor.{ UnstartedCell, ActorRef }
import akka.routing.{ RoutedActorRef, RoutedActorCell, Route } import akka.routing.{ RoutedActorRef, RoutedActorCell, Route }
/**
* This object can be used to extract the `Route` out of a RoutedActorRef.
* These are the refs which represent actors created from [[akka.actor.Props]]
* having a [[akka.routing.RouterConfig]]. Use this extractor if you want to
* test the routing directly, i.e. without actually dispatching messages.
*
* {{{
* val router = system.actorOf(Props[...].withRouter(new MyRouter))
* val route = ExtractRoute(router)
* route(sender -> message) must be(...)
* }}}
*/
object ExtractRoute { object ExtractRoute {
def apply(ref: ActorRef): Route = { def apply(ref: ActorRef): Route = {
@tailrec def rec(tries: Int = 10): Route = { @tailrec def rec(tries: Int = 10): Route = {