2015-09-13 3 views
2

Я много искал об этом и не получил ответа.Как насмехаться с актером на основе ActorSelection?

У меня есть актер "А" (пользователь/A) которые посылают сообщение "X" для другого актера "B" (пользователь/B) при получении сообщения "M". Для этого актера A Используйте ActorSelection мне нужно тест, когда я посылаю M к , B получит «X».

Я стараюсь сделать это с помощью TestProbe на «пользователь/B», но не имеет успеха.

Я также вижу некоторые подобные вопросы об этом, но каждый ответ сказал использовать ActorRef insted ActorSelection. Это не вариант для меня, мне действительно нужно использовать ActorSelection.

У кого-то есть идея?

+0

Почему вам нужно использовать 'ActorSelection'? – Ryan

+1

В моем случае у меня много актеров на пути «/ user/agents/*», но эти актеры - volatiI, и у меня нет «ActorRef» для всех участников. С другой стороны, у меня есть один актер «/ user/xpto», который отправляет сообщение «X» для «/ user/agents/*» всегда получает сообщение «M». Я не понимаю, почему так сложно издеваться над каким-то актером в системе акка. –

ответ

5

Простой ответ: вместо жесткого кодирования путь выбора в A делает это настраиваемым. В тесте вы можете указать это на путь TestProbe.

+0

Возможно, стоит отметить, что это сложнее сделать в текущей версии версии Akka, поскольку имена TestProbe не могут контролироваться (http://doc.akka.io/api/akka/2.3.14/index.html# akka.testkit.TestProbe $) Но в последнем кандидате на выпуск есть новый метод 'apply' для установки имени: http://doc.akka.io/api/akka/2.4.0-RC2/index. html # akka.testkit.TestProbe $ – mattinbits

+2

Вам не нужно управлять именем, так как вы можете получить его из 'probe.ref.path'. –

4

Вы можете написать простые помощники для своих тестов, которые называются вашими актерами, но направляют сообщения вашим зондам.

Предполагая, что это ваша установка (упрощенно):

case object M 
case object X 
class A extends Actor { 
    def receive = { 
    case M => context.system.actorSelection("/user/B") ! X 
    } 
} 

Вы хотите проверить актер A.

Вы можете написать такой «тест рамки» для вашего приложения:

object ForwardActor { 
    def props(to: ActorRef) = Props(new ForwardActor(to)) 
} 

class ForwardActor(to: ActorRef) extends Actor { 
    override def receive = { 
    case x => to forward x 
    } 
} 

def mock(name: String, probe: TestProbe)(implicit system: ActorSystem): Unit = 
    system.actorOf(ForwardActor.props(probe.ref), name) 

Тогда вы будете иметь возможность проверить актер A просто делать такой тест:

"A sends X to B after receiving M" in { 
    val probeB = TestProbe() 
    mock("B", probeB) 
    system.actorOf(Props(new A)) ! M 
    probeB expectMsg X 
}