java - 如何通过模拟其中的一种或多种方法来测试 Akka Actor 的功能

标签 java scala mocking akka actor

我很想知道如何测试 Akka Actor 的功能,通过模拟某些方法(用模拟的方法替换真实对象/actor 的方法实现)。

我使用akka.testkit.TestActorRef;

此外:我尝试使用 SpyingProducer 但不清楚如何使用它。 (就像我一样,如果我在它的实现中创建了 actor,它就会和我现在拥有的一样)。 关于那个的谷歌搜索结果不是很verbose .

我使用 powemockitojava。但这无关紧要。我很想知道原则上如何做到这一点 使用任何框架的任何语言

(so if you do not know how power/mockito works just provide your code.. (please) or complete idea about how you would do it with your tools you know.)

那么,假设我们有一个要测试的 Actor:

package example.formock;

import akka.actor.UntypedActor;

public class ToBeTestedActor extends UntypedActor {

    @Override
    public void onReceive(Object message) throws Exception {

        if (message instanceof String) {
            getSender().tell( getHelloMessage((String) message), getSelf());
        }

    }

    String getHelloMessage(String initMessage) { // this was created for test purposes (for testing mocking/spy capabilities). Look at the test
        return "Hello, " + initMessage;
    }

}

在我们的测试中,我们想要替换 getHelloMessage() 返回其他内容。

这是我的尝试:

package example.formock;

import akka.testkit.TestActorRef;
...

@RunWith(PowerMockRunner.class)
@PrepareForTest(ToBeTestedActor.class)
public class ToBeTestedActorTest {

    static final Timeout timeout = new Timeout(Duration.create(5, "seconds"));

    @Test
    public void getHelloMessage() {

        final ActorSystem system = ActorSystem.create("system");

        // given
        final TestActorRef<ToBeTestedActor> actorRef = TestActorRef.create(
                system,
                Props.create(ToBeTestedActor.class),
                "toBeTestedActor");

        // First try:
        ToBeTestedActor actorSpy = PowerMockito.spy(actorRef.underlyingActor());
        // change functionality
        PowerMockito.when(actorSpy.getHelloMessage (anyString())).thenReturn("nothing"); // <- expecting result   


        try {

           // when
           Future<Object> future = Patterns.ask(actorRef, "Bob", timeout);
           // then
           assertTrue(future.isCompleted());

            // when
           String resultMessage = (String) Await.result(future, Duration.Zero());
            // then
           assertEquals("nothing", resultMessage);  // FAIL HERE

        } catch (Exception e) {
           fail("ops");
        }
    }
}

结果:

org.junit.ComparisonFailure: 
Expected :nothing
Actual   :Hello, Bob

最佳答案

Akka 有一个 AutoPilot 类,它基本上是对 actor 的一般模拟,具有响应消息和断言消息已发送的能力。 http://doc.akka.io/docs/akka/snapshot/java/testing.html

这是该页面的 java 示例。您创建一个探测器,设置一个可以响应消息的自动驾驶仪,并从中获取一个 ActorRef,您可以用它代替您的真实 Actor 。

new JavaTestKit(system) {{
  final JavaTestKit probe = new JavaTestKit(system);
  // install auto-pilot
  probe.setAutoPilot(new TestActor.AutoPilot() {
    public AutoPilot run(ActorRef sender, Object msg) {
      sender.tell(msg, ActorRef.noSender());
      return noAutoPilot();
    }
  });
  // first one is replied to directly ...
  probe.getRef().tell("hello", getRef());
  expectMsgEquals("hello");
  // ... but then the auto-pilot switched itself off
  probe.getRef().tell("world", getRef());
  expectNoMsg();
}};

关于java - 如何通过模拟其中的一种或多种方法来测试 Akka Actor 的功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16715949/

相关文章:

java - `Set<Class<? extends Class<?>>> typeSet = resolverUtil.getClasses();`是什么意思?

scala - 您能推荐一些关于 Scala 哲学和程序设计的好的介绍吗?

scala - Clojure GUI 编程很难

Scala 解释器找不到我的类?

python - 如何模拟 python 的 read()

java - 如何在 java 8 中模拟 YearMonth

JavaFx TableView - 如果焦点被赋予同一列,则保存焦点丢失的编辑不起作用

java - 写入大格式 Excel (.xlsx) 时出现 Zip-bomb 异常

java - 如何使用 Class 作为泛型类型标记

scala - 将结构传递给 spark 中的 UDAF