Моя пьеса приложение использует AKKA актера для обработки длительных вычислений:Тестирование играть взаимодействие контроллера с AKKA актера
class MyController(myActor : ActorRef) extends Controller{
def doStuff = Action { implicit request =>
val response : Future[Any] = myActor ? DoStuff
Async{
response.map{
str : String => Ok(str)
}
}
}
}
Я пытаюсь проверить, что все работает должным образом. У меня есть отдельные тесты для проверки того, что актер ведет себя правильно и в основном просто хочет проверить, что контроллер отправляет правильные сообщения пользователю. Мой текущий подход вроде этого:
class MyControllerSpec extends Specification{
"MyController" should {
object DummyActor extends Actor{
def receive = {
case _ =>()
}
}
"do stuff properly" >> {
val probe = TestProbe()(Akka.system)
val test = new controllers.MyController(Akka.system.actorOf(Props(DummyActor))
val result = test.doStuff(FakeRequest())
probe.expectMsg(SomeMsg)
}
}
}
Контроллера посылает сообщение переданных в актере, когда действие DoStuff называется. Я пытаюсь проверить, отправлен ли правильный msg.
Я думаю, что test.doStuff запускается синхронно и время, когда фиктивный актер ничего не посылает. ОжиданиеMsg не запускается до тех пор, пока не будет возвращен вызов doStuff и уже отправлен SomeMsg. Как я могу решить эту проблему?
Вы правы. Я ошибся при изменении своего кода, чтобы использовать зонд вместо специального актера. Фиктивный актер даже не нужен. Тест теперь работает. Я хотел бы принять ваш ответ, но было бы здорово, если бы вы могли дать более подробное объяснение, почему это работает. Действительно ли вызов doStuff выполняется асинхронно, в отличие от того, что я сказал в вопросе? Может ли этот тест выйти из строя, если сообщение msg будет отправлено в ближайшее время? Благодарю. – mushroom
Насколько я понимаю в библиотеках тестов Akka, я думаю, что он запустит систему актеров с диспетчером, который выполняется в вызывающем потоке, поэтому отправка с помощью «actor! Message» фактически блокирует и возвращает завершенное будущее. – johanandren
С другой стороны, я только заметил, что ваш тест не использует тестовые материалы akka (TestBase и т. Д.), А только зонд. Поэтому, чтобы пересмотреть этот ответ, я думаю, что probe.expectMessage будет блокироваться с таймаутом по умолчанию и сбой, если сообщение не поступило. Вы можете указать другое значение таймаута, если хотите. – johanandren