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

时间:2012-11-14 22:28:37

标签: java unit-testing mocking akka

我对Akka很新,我正在尝试用Java编写一些单元测试。考虑以下演员:

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);
    }
  }

}

拦截来电new Helper().processWork(work)的正确方法是什么?另外,是否有任何推荐的方法在Java中使用Akka actor实现依赖注入?

提前致谢。

1 个答案:

答案 0 :(得分:4)

您的代码已经可以正常测试了:

  • 您可以单独测试您的业务逻辑,因为您可以在演员之外实例化Helper
  • 一旦你确定Helper做了它应该做的事情,只需向演员发送一些输入并观察正确的答复回来

现在,如果您需要“模拟”Worker来测试其他组件,那么根本不要使用Worker,而是使用TestProbe。你通常会得到工人的ActorRef,只需注入probe.getRef()

那么,如何注入?

我会假设你的另一个组件是一个Actor(因为否则你将无法应用你通常使用的注射技术)。然后有三个基本选择:

  1. 将其作为构造函数参数传递
  2. 在消息中发送
  3. 如果actor将ref作为其子元素创建,则传入Props,可能在另一个构造函数中传递
  4. 第三种情况可能就是你所看到的(我猜的是基于演员类的名字):

    public class MyParent extends UntypedActor {
      final Props workerProps;
    
      public MyParent() {
        workerProps = new Props(...);
      }
      public MyParent(Props p) {
        workerProps = p;
      }
    
      ...
      getContext().actorOf(workerProps, "worker");
    }
    

    然后你可以像这样注入一个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");