vegemite4me
vegemite4me

Reputation: 6896

Using Akka (with Java) how can I verify that my actor under test is watching another actor?

I have the following actor for which I would like to create unit tests to verify the following behaviour:

  1. ListeningActor correctly registers itself to watch the listeningTo actor.
  2. ListeningActor correctly kills itself when the listeningTo actor terminates.

How can I verify these two behaviours?

I am using Akka 2.0.2 with Java.

Thanks

public class ListeningActor extends UntypedActor {
    private final ActorRef listeningTo;

    public ListeningActor(final ActorRef listeningTo) {
        this.listeningTo = listeningTo;
    }

    @Override
    public void preStart() {
        super.preStart();
        context().watch(listeningTo);          // <---- To verify
    }

    @Override
    public void onReceive(final Object o) throws Exception {
        if (o instanceof Terminated) {
            Terminated terminated = (Terminated) o;
            if (terminated.equals(listeningTo)) {
                context().stop(self());        // <---- To verify
            }
        } else {
            unhandled(o);
        }
    }
}

Upvotes: 4

Views: 2823

Answers (4)

Jan-Terje S&#248;rensen
Jan-Terje S&#248;rensen

Reputation: 14708

If you are using JavaTestKit and akka version 2.4.2 you could solve it like this:

@Test
public void testThatPersistenceActorShutdown() {
    watch(persistenceActor);
    persistenceActor.tell(new Shutdown(), getRef());
    expectTerminated(persistenceActor);
}

You can find a working example here - akka-persistence-java-example

Upvotes: 3

vegemite4me
vegemite4me

Reputation: 6896

If it helps anyone, here's my final unit test:

public class ListeningActorTest
{
    private TestKit testKit;
    private TestActorRef<ListeningActor> listeningActor;
    private TestProbe listeningToActor;

    @Before
    public void setUp() throws Exception
    {
        testKit = new TestKit(ActorSystem.apply());
        listeningToActor = TestProbe.apply(testKit.system());
        listeningActor = TestActorRef.apply(new Props(new UntypedActorFactory()
        {
            @Override
            public Actor create()
            {
                return new ListeningActor(listeningToActor.ref());
            }
        }), testKit.system());
    }

    @Test
    public void shouldTerminateWhenTheListeningToActorTerminates()
    {
        //Given
        assertFalse(listeningActor.isTerminated());

        //When
        listeningToActor.testActor().tell(PoisonPill.getInstance());

        //Then
        assertTrue(listeningActor.isTerminated());
    }
}

Upvotes: 5

Viktor Klang
Viktor Klang

Reputation: 26597

Watch the ListenerActor with the testActor from TestKit, then expect the ListenerActor to be Terminated when you PoisonPill and-or stop an actor it listens to. Done.

Upvotes: 2

Eric Finn
Eric Finn

Reputation: 9015

Disclaimer: I am not familiar with akka.

Can you subclass ActorRef? If so, you can make a subclass specifically for testing which you can cause to send messages and be terminated. Then, in your unit tests, tell your instance of ListeningActor to be terminated, and verify that your ListeningActor instance has been stopped.

Upvotes: 0

Related Questions