简体   繁体   English

如何正确测试Java中的模拟Akka演员?

[英]How to properly test with mocks Akka actors in Java?

I'm very new with Akka and I'm trying to write some unit tests in Java. 我是Akka的新手,我正在尝试用Java编写一些单元测试。 Consider the following actor: 考虑以下actor:

public class Worker extends UntypedActor {

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

    if (message instanceof Work) {
      Work work = (Work) message;
      Result result = new Helper().processWork(work);
      getSender().tell(result, getSelf());
    } else {
      unhandled(message);
    }
  }

}

What is the proper way to intercept the call new Helper().processWork(work) ? 截取调用new Helper().processWork(work)的正确方法是什么? On a side note, is there any recommended way to achieve dependency injection within Akka actors with Java? 另外,是否有任何推荐的方法在Java中使用Akka actor实现依赖注入?

Thanks in advance. 提前致谢。

Your code is already properly testable: 您的代码已经可以正常测试:

  • you can test your business logic separately, since you can just instantiate your Helper outside of the actor 您可以单独测试业务逻辑,因为您可以在actor之外实例化Helper
  • once you are sure that the Helper does what it is supposed to do, just send some inputs to the actor and observe that the right replies come back 一旦你确定Helper做了它应该做的事情,只需向演员发送一些输入并观察正确的回复是否会回来

Now if you need to have a “mocked” Worker to test some other component, just don't use a Worker at all, use a TestProbe instead. 现在,如果您需要一个“模拟” Worker来测试其他组件,那么根本不要使用Worker,而是使用TestProbe Where you would normally get the ActorRef of the Worker, just inject probe.getRef() . 你通常会获得Worker的ActorRef ,只需注入probe.getRef()

So, how to inject that? 那么,如何注入呢?

I'll assume that your other component is an Actor (because otherwise you won't have trouble applying whatever injection technique you normally use). 我假设你的另一个组件是一个Actor(因为否则你将无法应用你通常使用的任何注入技术)。 Then there are three basic choices: 然后有三个基本选择:

  1. pass it in as constructor argument 将其作为构造函数参数传递
  2. send it within a message 在消息中发送它
  3. if the actor creates the ref as its child, pass in the Props , possibly in an alternative constructor 如果actor将ref作为其子Props创建,则传入Props ,可能在另一个构造函数中

The third case is probably what you are looking at (I'm guessing based on the actor class' name): 第三种情况可能就是你所看到的(我猜是基于演员类的名字):

public class MyParent extends UntypedActor {
  final Props workerProps;

  public MyParent() {
    workerProps = new Props(...);
  }
  public MyParent(Props p) {
    workerProps = p;
  }

  ...
  getContext().actorOf(workerProps, "worker");
}

And then you can inject a TestProbe like this: 然后你可以像这样注入一个TestProbe

final TestProbe probe = new TestProbe(system);
final Props workerMock = new Props(new UntypedActorFactory() {
  public UntypedActor create() {
    return new UntypedActor() {
      @Override
      public void onReceive(Object msg) {
        probe.getRef().tell(msg, getSender());
      }
    };
  }
});
final ActorRef parent = system.actorOf(new Props(new UntypedActorFactory() {
  public UntypedActor create() {
    return new MyParent(workerMock);
  }
}), "parent");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM