我是新來的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