/** * Copyright (C) 2014-2015 Typesafe Inc. */ package docs.testkit; import static org.junit.Assert.*; import akka.actor.*; import akka.japi.Creator; import akka.japi.Function; import akka.testkit.AkkaJUnitActorSystemResource; import akka.testkit.TestActorRef; import akka.testkit.TestProbe; import com.typesafe.config.ConfigFactory; import org.junit.ClassRule; import org.junit.Test; public class ParentChildTest { @ClassRule public static AkkaJUnitActorSystemResource actorSystemResource = new AkkaJUnitActorSystemResource("TestKitDocTest", ConfigFactory.parseString("akka.loggers = [akka.testkit.TestEventListener]")); private final ActorSystem system = actorSystemResource.getSystem(); //#test-example static class Parent extends UntypedActor { final ActorRef child = context().actorOf(Props.create(Child.class), "child"); boolean ponged = false; @Override public void onReceive(Object message) throws Exception { if ("pingit".equals(message)) { child.tell("ping", self()); } else if ("pong".equals(message)) { ponged = true; } else { unhandled(message); } } } static class Child extends UntypedActor { @Override public void onReceive(Object message) throws Exception { if ("ping".equals(message)) { context().parent().tell("pong", self()); } else { unhandled(message); } } } //#test-example static //#test-dependentchild class DependentChild extends UntypedActor { private final ActorRef parent; public DependentChild(ActorRef parent) { this.parent = parent; } @Override public void onReceive(Object message) throws Exception { if ("ping".equals(message)) { parent.tell("pong", self()); } else { unhandled(message); } } } //#test-dependentchild static //#test-dependentparent class DependentParent extends UntypedActor { final ActorRef child; boolean ponged = false; public DependentParent(Props childProps) { child = context().actorOf(childProps, "child"); } @Override public void onReceive(Object message) throws Exception { if ("pingit".equals(message)) { child.tell("ping", self()); } else if ("pong".equals(message)) { ponged = true; } else { unhandled(message); } } } //#test-dependentparent static //#test-dependentparent-generic class GenericDependentParent extends UntypedActor { final ActorRef child; boolean ponged = false; public GenericDependentParent(Function childMaker) throws Exception { child = childMaker.apply(context()); } @Override public void onReceive(Object message) throws Exception { if ("pingit".equals(message)) { child.tell("ping", self()); } else if ("pong".equals(message)) { ponged = true; } else { unhandled(message); } } } //#test-dependentparent-generic @Test public void testingWithoutParent() { TestProbe probe = new TestProbe(system); ActorRef child = system.actorOf(Props.create(DependentChild.class, probe.ref())); probe.send(child, "ping"); probe.expectMsg("pong"); } @Test public void testingWithCustomProps() { TestProbe probe = new TestProbe(system); Props childProps = Props.create(MockedChild.class); TestActorRef parent = TestActorRef.create(system, Props.create(DependentParent.class, childProps)); probe.send(parent, "pingit"); // test some parent state change assertTrue(parent.underlyingActor().ponged == true || parent.underlyingActor().ponged == false); } @Test public void testingWithChildProbe() throws Exception { final TestProbe probe = new TestProbe(system); //#child-maker-test Function maker = new Function() { @Override public ActorRef apply(ActorRefFactory param) throws Exception { return probe.ref(); } }; ActorRef parent = system.actorOf(Props.create(GenericDependentParent.class, maker)); //#child-maker-test probe.send(parent, "pingit"); probe.expectMsg("ping"); } public void exampleProdActorFactoryFunction() throws Exception { //#child-maker-prod Function maker = new Function() { @Override public ActorRef apply(ActorRefFactory f) throws Exception { return f.actorOf(Props.create(Child.class)); } }; ActorRef parent = system.actorOf(Props.create(GenericDependentParent.class, maker)); //#child-maker-prod } static //#test-fabricated-parent-creator class FabricatedParentCreator implements Creator { private final TestProbe proxy; public FabricatedParentCreator(TestProbe proxy) { this.proxy = proxy; } @Override public Actor create() throws Exception { return new UntypedActor() { final ActorRef child = context().actorOf(Props.create(Child.class), "child"); @Override public void onReceive(Object x) throws Exception { if (sender().equals(child)) { proxy.ref().forward(x, context()); } else { child.forward(x, context()); } } }; } } //#test-fabricated-parent-creator @Test public void fabricatedParentTestsItsChildResponses() throws Exception { // didn't put final on these in order to make the parent fit in one line in the html docs //#test-fabricated-parent TestProbe proxy = new TestProbe(system); ActorRef parent = system.actorOf(Props.create(new FabricatedParentCreator(proxy))); proxy.send(parent, "ping"); proxy.expectMsg("pong"); //#test-fabricated-parent } }