Ich versuche, eine Testsonde zu erhalten, mit einer Bestätigung zu antworten, wenn es irgendeine Nachricht erhält.Akka Actor Test: Automatische Antwort mit einer TestProbe
Ich schrieb den folgenden Code in meinem Test, aber es funktioniert nicht:
val chgtWriter = new TestProbe(system) {
def receive: Receive = {
case m => println("receive messagereplying with ACK"); sender() ! ACK
}
}
Gibt es eine Möglichkeit, das zu tun. Der Akteur, der die Nachricht tatsächlich an die Testsonde sendet, läuft definitiv auf einem anderen Thread als TestThread. Unten können Sie den vollständigen Test sehen, wie er derzeit erstellt wird.
feature("The changeSetActor periodically fetch new change set following a schedule") {
scenario("A ChangeSetActor fetch new changeset from a Fetcher Actor that return a full and an empty ChangeSet"){
Given("a ChangeSetActor with a schedule of fetching a message every 10 seconds, a ChangeFetcher and a ChangeWriter")
val chgtFetcher = TestProbe()
val chgtWriter = new TestProbe(system) {
def receive: Receive = {
case m => println("receive message {} replying with ACK"); sender() ! ACK
}
}
val fromTime = Instant.now().truncatedTo(ChronoUnit.SECONDS)
val chgtActor = system.actorOf(ChangeSetActor.props(chgtWriter.ref, chgtFetcher.ref, fromTime))
When("all are started")
Then("The Change Fetcher should receive at least 3 messages from the ChangeSetActor within 40 seconds")
var changesetSNum = 1
val received = chgtFetcher.receiveWhile(40 seconds) {
case FetchNewChangeSet(m) => {
println(s"received: FetchNewChangeSet(${m}")
if (changesetSNum == 1) {
chgtFetcher.reply(NewChangeSet(changeSet1))
changesetSNum += 1
}
else
chgtFetcher.reply(NoAvailableChangeSet)
}
}
received.size should be (3)
}
}
Der changeSetActor vollständig getestet und funktioniert. Der Test hängt mit dem ChangeWriter. Es empfängt nie eine Nachricht in der Empfangs-Methode.
EDIT1 (Nach @Jakko Anser)
Die Auto Pilots ist wie folgt:
val probe = TestProbe() probe.setAutoPilot(new TestActor.AutoPilot { def run(sender: ActorRef, msg: Any): TestActor.AutoPilot = msg match { case "stop" ⇒ TestActor.NoAutoPilot case x ⇒ **testActor.tell(x, sender)**; TestActor.KeepRunning } })
Obwohl die ganze Erklärung so weit nachgegeben klar ist, was in der verwirrend offizielles Beispiel ist die Referenz "testActor". Wer ist testActor hier? Zu diesem Zeitpunkt gibt es keine variable Deklaration dieses Namens.
Hinzugefügt fehlende 'KeepRunning' und einige Details, wie man es benutzt. –
Ich habe nicht genug Rep, um den ursprünglichen Post zu kommentieren, also werde ich einfach meine Kommentare hier hinzufügen. 'target.tell (message, source)' ist fast gleichbedeutend mit 'target! Nachricht ": Beide senden eine Nachricht an' target'. Der Unterschied besteht darin, dass Sie den Absender der Nachricht explizit mit '.tell()' angeben müssen, aber mit '!' Wird der Absender implizit ausgewählt. Wenn Sie '!' In einem Akteur aufrufen, wird der Akteur als Absender verwendet. –
Ich habe die Frage mit Update von Ihrer Antwort bearbeitet. Ich denke, die Frage ist hier, warum Sie Absender verwenden! ACK anstelle von testActor.tell (ACK, Absender).Ich weiß nicht, was die Variable testActor im ursprünglichen Beispiel darstellt. Am wichtigsten ist, wo es definiert ist. – MaatDeamon