jacomus
jacomus

Reputation: 51

Akka JavaTestKit JUnit Message not sent to default/user

I'm writing a Akka JUnit test, using the JavaTestKit and I'm trying to figure out what I'm doing wrong.

I've got a AkkaSystem that I use to create an Inbox object and send a message to a ExecutiveSupervisor.

ActorSystem akkaSystem = ActorSystem.create("myAkkaSystem");

Props executiveProps = Props.create(ExecutiveSupervisor.class);
TestActorRef<ExecutiveSupervisor> executiveSupervisorTestActorRef = TestActorRef.create(akkaSystem, executiveProps, "testExecutiveSupervisor");

new JavaTestKit(akkaSystem) {{

    final Inbox inbox = Inbox.create(akkaSystem);
    inbox.send(executiveSupervisorTestActorRef, new Object());
    ResultAndData result = (Object)inbox.receive(Duration.create(2, TimeUnit.SECONDS));

 }};

The ResultAndData object is passed into the ExecutiveSupervisor class that is an UnTypedActor and is received correctly when I look at it while debugging.

Execution goes through the code in the actor very happily. At a point in the worker I expect it to return the same object it was passed, (ResultAndData) to the Inbox of the JUnit at test at ActorSystem level. I.e. I want the worker to return to its parent the same object it was passed.

But then, just as it tries to return with the below line:

log.info("SUCCESS!!!!!!!!!!!");
getContext().parent().tell(result, getSelf());  //FAILS HERE

At which point I get this message:

[INFO] [09/30/2013 19:22:38.609] [default-akka.actor.default-dispatcher-4] [akka://default/user] Message [com.netaporter.modules.serviceagent.remoteservices.ResultAndData] from TestActor[akka://default/user/testExecutiveSupervisor] to Actor[akka://default/user] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.

Basically the message is describes exactly what I want to happen, but it just doesn't. I want a ResultAndData object returned from the testExecutiveSupervisor to its parent the default/user.

If I put a line in the JUnit:

expectMsgEquals(duration("2 seconds"), result);

with "result" being my ResultAndData object it will always time out as the message doesn't get through.

Thanks all, any help would be great.

Upvotes: 1

Views: 560

Answers (1)

pushy
pushy

Reputation: 9635

You should return the message like this:

sender().tell(result, getSelf());

Right now you are sending the message to the parent of your actor, as your actor is a top-level actor this will not succeed. The parent of your actor is not the inbox, so what you are trying cannot succeed. The parent is the actor that creates the child on its context, as you create the Actor through TestActorRef on the actorSystem, it will be a top-level actor with the default/user Actor as a parent, which you cannot use for receiving messages. I suspect what you really want is to respond to the message, therefore you should send your message to the sender of the current message, which you can retrieve by using sender().

Upvotes: 2

Related Questions