本文介绍了如何通过模拟其中的一个或多个方法来测试Akka Actor功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm interested to know about how to test Akka Actor functionality, by mocking some methods (substitute real object's/actor's method implementation by mocked one) in Actor.

我使用 akka.testkit.TestActorRef ;

另外:我尝试使用 SpyingProducer ,但目前尚不清楚如何使用它。 (就像我,如果我在其实现中创建了actor,它将与我现在一样)。
google搜索结果不是很明显。

Also: I tried to use SpyingProducer but it is not clear how to use it. (like I if I created actor inside its implementation it would be the same I have now).The google search result about that is not very verbose.

我使用 powemockito java 。但是这没关系。我有兴趣知道原则上怎么做 任何带有任何框架的语言

I use powemockito and java. But It does not matter. I would be interested to know how to do it in principle with any language with any framework

所以,假设我们有一个要测试的演员:

So, let's say we have an Actor to test:

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()返回其他内容。

And in our test we want to substitute getHelloMessage() returning something else.

这是我的尝试:

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 这基本上是演员的一般模拟,具有响应消息和断言消息发送的能力。

Akka has a class AutoPilot that is basically a general mock for actors, with the ability to respond to messages and assert that messages were sent.http://doc.akka.io/docs/akka/snapshot/java/testing.html

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

Here's the java example for that page. You create a probe, set an auto-pilot that can respond to messages, and get an ActorRef from it that you can substitute in for your real 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();
}};

这篇关于如何通过模拟其中的一个或多个方法来测试Akka Actor功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-25 10:25