2013-10-07 3 views
0

Mon application de jeu utilise un acteur akka pour gérer un calcul long cours d'exécution:Test jeu l'interaction du contrôleur avec un acteur 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) 
     } 
    } 
    } 
} 

Je suis en train de tester que les choses fonctionnent correctement. J'ai des tests séparés pour vérifier que l'acteur se comporte correctement et surtout je veux juste vérifier que le contrôleur envoie les bons msgs à l'acteur. Mon approche actuelle est un peu comme ceci:

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) 
    } 
    } 
} 

Le contrôleur envoie un message au passé dans l'acteur lorsque l'action doStuff est appelée. J'essaie de vérifier que le bon message est envoyé.

Je pense que test.doStuff est exécuté de façon synchrone et expire lorsque l'acteur factice n'envoie rien. Le paramètre expectMsg ne démarre qu'après l'envoi de l'appel doStuff et l'envoi de SomeMsg. Comment puis-je résoudre ce problème?

Répondre

1

N'est-ce pas ce que vous voulez faire passer la sonde à votre contrôleur plutôt qu'une implémentation d'acteur factice, comment quelque chose serait-il envoyé à la sonde si ce n'est pas le cas?

+0

Vous avez raison. J'ai fait une erreur en changeant mon code pour utiliser la sonde au lieu d'un acteur spécial. L'acteur factice n'est même pas nécessaire. Le test fonctionne maintenant. Je voudrais accepter votre réponse, mais ce serait bien si vous pouviez fournir plus d'explications sur la raison pour laquelle cela fonctionne. Est-ce que l'appel à doStuff est réellement exécuté de manière asynchrone, contrairement à ce que j'ai dit dans la question? Ce test peut-il échouer si le message est envoyé à bientôt? Merci. – mushroom

+0

En ce qui concerne les bibliothèques de test Akka, je pense qu'il va lancer le système d'acteur avec un répartiteur qui s'exécute sur le thread appelant, donc envoyer avec "acteur! Message" bloquera et retournera un futur complété. – johanandren

+0

A la deuxième réflexion, je viens de remarquer que votre test n'utilise pas le test akka (TestBase etc), mais seulement la sonde. Donc pour réviser cette réponse, je pense que probe.expectMessage va bloquer avec un timeout par défaut et échouer si le message n'est pas arrivé. Vous pouvez spécifier une valeur de délai d'expiration différente si vous le souhaitez. – johanandren

Questions connexes