2015-10-21 6 views
1

Я пытаюсь протестировать актера A внутри приложения Play 2.4 с Scaldi. Этот актер звонит injectActorRef[B], который я хочу высмеять с помощью TestKit.TestProbe.Scaldi: Bind [T <AkkaInjectable] to TestProbe.ref

Внутри моих спецификаций2, я хотел бы иметь возможность получить зонд для издевательства B, предоставив соответствующий TestKit.TestProbe.ref для актера A.

Я хотел бы сделать что-то вроде этого:

implicit val inj = (new TestModule(){ 
    bind[TestProbe] identifiedBy 'probeForB to TestProbe() 
    bind[B] to inject[TestProbe]('probeForB).ref 
}).injector 

inject[TestProbe]('probeForB).expectMsgType[] must ... 

Вопрос заключается в том, что ссылка является ActorRef и, следовательно, не соответствует ожидаемому B типа.

Есть ли чистый способ сделать это? Можно ли указать ActorRef для возврата injectActorRef[B]?


Я закончил переопределять привязку для Актера A.

val probeForB = TestProbe() 

implicit val inj = (new Module() { 
    bind[A] to new A() { 
     override def injectB(): ActorRef = probeForB.ref 
    } 
}).injector 

ответ

1

Как упоминалось выше, проблема в том, что inject[TestProbe]('probeForB).ref дает вам ActorRef назад вместо экземпляра фактического актера.

Если вы хотите протестировать его так, как вы описали, вам необходимо определить привязку ActorRef для актера B. Например:

bind [BActor] toProvider new BActor 
bind [ActorRef] identifiedBy 'bRef to { 
    implicit val system = inject [ActorSystem] 
    injectActorRef[BActor] 
} 

Когда вы имеете эту установку, то вы можете переопределить второе связывание с пробником:

bind [ActorRef] identifiedBy 'bRef to inject[TestProbe]('probeForB).ref 

Пожалуйста, обратите внимание, что этот пример не является прямым эквивалентом, поскольку BActor теперь имеет другой супервайзер (актер-опекун, поэтому нам нужно ввести ActorSystem здесь).

injectActorRef делегирует создание актера «контексту» (родительскому актеру или актерской системе) с context.actorOf. Что делает его полезным, так это то, что он создает специальный Props, который вводит новые экземпляры класса BActor, когда akka хочет его создать. Это означает, что scaldi не имеет контроля над жизненным циклом актера (это очень важно, поскольку сама акка имеет очень сложные механизмы для этого), это просто дает akka знания о том, как создавать новые экземпляры определенного класса актера.

Если вы создаете актера внутри другого актера (как вы описали), то жизненный цикл их обоих сильно связан и управляется аккой. Вот почему в этом случае вы не можете просто переопределить и привязать Actor к привязке ActorRef для тестов.

+0

Потеря отношения родитель-ребенок не является вариантом в моем случае. Я попытаюсь взглянуть на 'class TestActorRef'. –