Я пытаюсь получить пробный зонд для ответа с подтверждением, когда он получает какое-либо сообщение.Акка Тест актера: автоматический ответ с помощью TestProbe
Я написал следующий код в моем тесте, но он не работает:
val chgtWriter = new TestProbe(system) {
def receive: Receive = {
case m => println("receive messagereplying with ACK"); sender() ! ACK
}
}
Есть ли способ сделать это. Актер, фактически отправляющий сообщение на тестовый зонд, определенно работает в другом потоке, чем TestThread. Ниже вы можете увидеть полный тест, как в настоящее время созданный.
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)
}
}
changeSetActor полностью протестирована и работает. Тест зависает с ChangeWriter. Он никогда не получает сообщение в методе приема.
EDIT1 (После @Jakko Anser)
Auto Pilots выглядит следующим образом:
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 } })
Хотя все объяснение до сих пор путь понятно, что сбивает с толку в Официальным примером является ссылка «testActor». Кто здесь testActor? в этой точке нет объявления переменной этого имени.
Добавлен недостающий 'KeepRunning' и некоторые сведения о том, как его использовать. –
У меня недостаточно комментариев, чтобы прокомментировать исходное сообщение, поэтому я просто добавлю свои комментарии здесь. 'target.tell (message, source)' почти эквивалентен 'target! message': оба отправляют сообщение «target». Разница заключается в том, что вы должны явно указывать отправителя сообщения с '.tell()', но с '!' Отправитель будет выбран неявно. Если вы вызываете '!' Внутри актера, актер будет использоваться в качестве отправителя. –
Я отредактировал вопрос с обновлением из вашего ответа. Я думаю, вопрос здесь в том, почему вы используете отправителя! ACK вместо testActor.tell (ACK, отправитель).Я не знаю, что представляет переменная testActor в исходном примере. Самое главное, где это определено. – MaatDeamon