Предоставление ActorPath для testProbe
У меня есть код, который отправляет сообщение актеру, используя его ActorPath not ActorRef
system.actorSelection("/user/myActor") ! "a message"
Мне нужно убедиться, что это сообщение действительно отправлено. Поэтому мне нужно в своих тестах создать testProbe (или что-то подобное), который живет на этом пути, так что он получит это сообщение.
val probe = TestProbe()
val system.actorOf(probe.ref, "myActor") // ??? I want to give my probe name and path
Ответы
Ответ 1
Контуры жесткого кодирования, скорее всего, сделают вас несчастными позже, поэтому вы должны с трудом проверить его как подсказку дизайна. Я бы рекомендовал использовать ActorRef в качестве первого выбора, и только если это не может быть сделано для работы, вернитесь к ActorPath, но затем держите его гибким, сообщив игроку, какой путь использовать (в сообщении или через конструктор).
Ответ 2
Я выяснил не элегантное решение.
Я определил помощника-актера под названием "ForwardActor"
class ForwardActor(to: ActorRef) extends Actor {
def receive = {
case x => to.forward(x)
}
}
то в моем тестовом случае
val probe = TestProbe()
val system.actorOf(Props(new ForwardActor(probe.ref)), "myActor")
probe.expectMsg(...)
Ответ 3
Предположим, что вы хотите протестировать этот код:
def f(as: ActorSelection): Unit = as ! "msg"
Затем вы можете использовать TestProbe
с ActorSelection
:
val p = TestProbe()
val as = system.actorSelection(p.ref.path)
f(as)
p.expectMsg("msg")
Ответ 4
Я разработал небольшую библиотеку /DSL для работы с такими случаями (она также позволяет создавать более сложные иерархии и прослушивать сообщения для определенных элементов пути) https://github.com/stanislav-chetvertkov/spy-tree. Вышеупомянутый случай может быть рассмотрен следующим образом:
import com.github.spytree.ActorListenersDSL._
val myActorProbe = TestProbe()
("myActor" replyTo myActorProbe.ref).materialize
context.actorSelection("/user/myActor") ! "a message"
val response = myActorProbe.expectResponse[String]
response.message shouldBe "a message"