我是akka的新手,我正在java上尝试akka。我想了解演员内部业务逻辑的单元测试。我阅读了文档,演员中孤立的业务逻辑的唯一例子是:
static class MyActor extends UntypedActor {
public void onReceive(Object o) throws Exception {
if (o.equals("say42")) {
getSender().tell(42, getSelf());
} else if (o instanceof Exception) {
throw (Exception) o;
}
}
public boolean testMe() { return true; }
}
@Test
public void demonstrateTestActorRef() {
final Props props = Props.create(MyActor.class);
final TestActorRef<MyActor> ref = TestActorRef.create(system, props, "testA");
final MyActor actor = ref.underlyingActor();
assertTrue(actor.testMe());
}
虽然这很简单,但这意味着我要测试的方法是公开的。但是,考虑到参与者应该只通过消息进行通信,我的理解是没有理由拥有公共方法,所以我将我的方法设为私有。如下例所示:
public class LogRowParser extends AbstractActor {
private final Logger logger = LoggerFactory.getLogger(LogRowParser.class);
public LogRowParser() {
receive(ReceiveBuilder.
match(LogRow.class, lr -> {
ParsedLog log = parse(lr.rowText);
final ActorRef logWriter = getContext().actorOf(Props.create(LogWriter.class));
logWriter.tell(log, self());
}).
matchAny(o -> logger.info("Unknown message")).build()
);
}
private ParsedLog parse(String rowText) {
// Log parsing logic
}
}
所以要测试方法parse
我要么:
- 需要它使包私有
- 或者测试演员的公共接口,即下一个演员
LogWriter
从我的演员那里收到正确的解析消息LogRowParser
我的问题:
- 选项#1 有什么缺点吗?假设参与者仅通过消息进行通信,封装和干净的开放接口就不那么重要了吗?
- 如果我尝试使用选项#2,有没有办法在下游测试中捕获从参与者发送的消息(测试
LogRowParser
和捕获LogWriter
)?我查看了各种示例,JavaTestKit
但所有示例都捕获了返回给发件人的响应消息,并且没有一个显示如何拦截发送给新参与者的消息。 - 我还有其他选择吗?
谢谢!
UPD: 忘了提到我还考虑了以下选项:
- 将逻辑从actors中完全移到辅助类中。akka 是常见的做法吗?
- Powermock ......但如果可以重新设计,我会尽量避免它