Cover Image for AkkaのActorをテストする(Java編)

AkkaのActorをテストする(Java編)

この記事は最終更新日から6年以上が経過しています。

AkkaのActorをテストする(Java編)

AkkaのActorをテストした時のメモ。 メモなので間違ってたら指摘いただけるとありがたいです。

事前準備

テストで使用するサンプルActor

static class MyActor extends UntypedActor {
  public void onReceive(Object o) throws Exception {
    if (o.equals("say42")) {
      getSender().tell(42, getSelf());
    } else if (o instanceof Exception) {
      throw (Exception) o;
    }
  }
  public boolean testMe() { return true; }
}

TIPS

適当なActorを作りたい

@Test
public void testActor() {
    new JavaTestKit(system) {{
        final TestProbe worker = new TestProbe(system);
        ActorRef workerActorRef = worker.ref(); // ActorRefを取得できる
    }};
}

ActorRefを引数に取るメソッドや、ActorRefをメッセージとしてやり取りする時に使う

Actorインスタンス内のメソッドをテストする

@Test
public void demonstrateTestActorRef() {
  final Props props = Props.create(MyActor.class);
  final TestActorRef<MyActor> ref = TestActorRef.create(system, props, "testA");
  final MyActor actor = ref.underlyingActor(); // Actorインスタンスの取得
  assertTrue(actor.testMe());
}

通常ActorRefからはActorのインスタンスを取得することはできないが、 TestActorRefをつかうとActorのインスタンスを取得出来るようになる。 取得したインスタンスでメソッドを実行することで単体テストする

メッセージ受信のテスト

@Test
public void testActorRef() {
        new JavaTestKit(system) {{
            final TestProbe aggregator = new TestProbe(system);

            String message = "test message";
            aggregator.ref().tell(message, getRef());
            aggregator.expectMsg(message);
            assertEquals(getRef(), aggregator.lastSender());
        }};
}

TestProbeを使って適当なActorを作る。 ActorRefを取得してメッセージを送信して、expectMsgでメッセージが受信されたことのテストをする。 lastSender()でどこからメッセージが来たかもテスト出来る

Actor停止挙動のテスト

@Test
public void testActorRef() {
    new JavaTestKit(system) {{
      final Props props = Props.create(MyActor.class);
      final TestActorRef<MyActor> target = TestActorRef.create(system, props, "testA");

      final JavaTestKit probe = new JavaTestKit(system);
      probe.watch(target);
      target.tell(PoisonPill.getInstance(), ActorRef.noSender());
      final Terminated msg = probe.expectMsgClass(Terminated.class);
      assertEquals(msg.getActor(), target);
    }};
}

targetをJavaTestKitで監視しておいて、PoisonPillを送る。 そのあと、Terminatedメッセージを受信することを確認する 応用すれば、他のアクターを殺すようなReaperのテストでも使えそう。

参考

  • http://doc.akka.io/docs/akka/2.4.0/java/testing.html#Built-In_Assertions
  • http://qiita.com/reoring/items/3baeac37ba0d63f39693