我是新来的AKK,我正在尝试在Java上akka。我想了解演员中业务逻辑的单元测试。我读documentation和孤立的业务逻辑的演员中唯一的例子是: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: 忘了提,我也算是类似的选项:
- 移动逻辑出来的演员完全进入辅助类。对阿卡来说常见的做法是?
- Powermock ...但我试图避免它,如果重新设计,可以
非常感谢答案和这部分具体_ ActorRef不公开任何内部状态或该演员类的方法。这是演员system_的一大卖点之一,它不仅回答我的问题,而且帮助我更好地理解演员模型 – 2015-04-02 13:58:13
你是对的(我投了你的答案),但你实际上没有回答任何具体问题。假设你不能改变给定的代码库,你将如何行动? – 2015-04-15 10:09:04
@JamesSharp,我加了一点点细节。我没有直接回答这些问题,但我确实提供了我认为是测试演员的合理方法。希望这可以帮助。 – cmbaxter 2015-04-15 13:07:30