Акка и Java 8 TestKit на примере - PullRequest
0 голосов
/ 16 октября 2018

Java 8 и Akka 2.12: 2.5.16 здесь.Я пытаюсь написать свой первый (когда-либо) модульный тест Akka, использующий Akka TestKit , и изо всех сил пытаюсь применить принципы, которые я вижу в (очень немногих) примерах, которые мне удалось найти в Интернете.

Мои актеры:

public class Child extends AbstractActor {
    @Override
    public Receive createReceive() {
        return receiveBuilder()
            .match(Init.class, init -> {
                int workUnit = workService.doSomeWork();
                log.info("Performed work on {}", workUnit);
            }).build();
    }
}

public class Master extends AbstractActor {
    @Inject @Named("CHILD")
    private ActorRef child;

    @Override
    public Receive createReceive() {
        return receiveBuilder()
            .match(Init.class, init -> {
                child.tell(init, self());
            }).build();
    }
}

Очень, очень просто.Итак, теперь я просто хочу написать модульные тесты, которые проверяют, что, когда субъект Master получает сообщение Init, он перенаправляет это сообщение в свой субъект Child.Моя лучшая попытка на данный момент:

@RunWith(MockitoJUnitRunner.class)
public class MasterTest {
    private ActorSystem actorSystem;

    @Before
    public void setup() {
        actorSystem = ActorSystem.create("test-system");
    }

    @After
    public void teardown() {
        Duration duration = Duration.create(10L, TimeUnit.SECONDS);
        TestKit.shutdownActorSystem(actorSystem, duration, true);
        actorSystem = null;
    }

    @Test
    public void onInit_shouldSendFordwardToChild() {
        // Given
        TestKit testKit = new TestKit(actorSystem);
        ActorRef master = actorSystem.actorOf(Props.create(Master.class, testKit));

        // When
        master.tell(new Init(), ActorRef.noSender());

        // Then
        testKit.expectMsg(Init.class);
    }
}

Когда я запускаю это, я получаю:

java.lang.IllegalArgumentException: no matching constructor found on class com.me.myapp.Master for arguments [class akka.testkit.TestKit]

Может кто-нибудь помочь мне подключить экземпляр TestKit к моему Master актеру, итакже помогите мне разобраться, как сделать рефакторинг MasterTest таким, чтобы он проверял, чего я пытаюсь достичь?Заранее спасибо!

1 Ответ

0 голосов
/ 18 октября 2018

Я понял это, не могу поверить, как трудно было заставить это работать: - /

В application.conf:

MyAkkApp {
  akka {
    remote {
      enabled-transports = ["akka.remote.netty.tcp"]
      netty.tcp {
        hostname = "127.0.0.1"
        port = 2553
      }
    }
  }
}

Тогда:

@RunWith(MockitoJUnitRunner.class)
public class MasterTest extends TestKit {
    static ActorSystem actorSystem = ActorSystem.create("MyAkkaApp",
        ConfigFactory.load().getConfig("MyAkkaApp"));

    static TestProbe child;  // The mock child
    static ActorRef master;

    @BeforeClass
    public static void setup() {
        child = new TestProbe(actorSystem, "Child");
        master = actorSystem.actorOf(Props.create(new Creator<Actor>() {
            @Override
            public Actor create() throws Exception {
                return new Master(child.ref());
            }
        }));
    }

    public MasterTest() {
        super(actorSystem);
    }

    @Test
    public void onInit_shouldSendFordwardToChild() {
        // Given
        Init init = new Init();

        // When
        master.tell(init, super.testActor());

        // Then
        child.expectMsg(init);  // Child should have received it
        expectNoMessage();  // Master should not be returning to sender
    }
}

Давай, Акка, ребята!Поддержка приводит к принятию, принятие ведет к стандартизации, стандартизация означает, что вы можете продавать 6-значные корпоративные лицензии на поддержку.

...