2014-09-22 5 views
5

Ho seguente errore supervisor test:Akka movimentazione

class Supervisor(dataProvider: DatabaseClientProvider) extends Actor { 
    val writer = context.actorOf(Props(classOf[Child], dataProvider.get)) 
    def receive: Receive = { 
    case Msg => writer forward msg 
    } 
    override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 100) { 
    case e: ConnectionException => Resume 
    } 
} 

class Child(db: DatabaseClient) extends Actor { 
    def receive: Receive = { 
    case msg:Msg => db.write(text) 
    } 
} 

voglio unit test sopra il codice in fondo io sto cercando di assicurarsi che quando l'eccezione si verifica, siamo ancora di riprendere il trattamento, come potete vedere qui sotto. Il problema è che nessuna eccezione viene catturata dal supervisore. Qual è il modo migliore per testare il codice qui sotto?

"resume handling messages when exception occurs" in { 

    // Given 
    val msg1 = Msg("Some msg1") 
    val msg2 = Msg("Some msg2") 

    //Throw an exception when attempting to write msg1 
    val databaseClient = mock[DatabaseClient] 
    when(databaseClient.write(msg1.text).thenThrow(ConnectionException("Error!")) 

    val dataProvider = mock[DatabaseClientProvider] 
    when(dataProvider.get).thenReturn(databaseClient) 

    val supervisor = system.actorOf(Props(new Supervisor(dataProvider))) 

    // When 
    intercept[ConnectionException] { 
     supervisor ! msg1 
    } 

    // When 
    supervisor ! msg2 

    // Then 
    verify(databaseClient.write("Some msg"), times(2)) 
} 

risposta

8

Per testare il comportamento del supervisore quando un bambino genera un'eccezione è necessario testare il supervisorStrategy. Utilizzando un TestActorRef, è possibile ottenere l'accesso alla funzione parziale s' il supervisorStrategy e affermare che una determinata Exception risultati del previsto Directive

val supervisor = TestActorRef[Supervisor](Props(new Supervisor(dataProvider))) 
val strategy = supervisor.underlyingActor.supervisorStrategy.decider 
strategy(ConnectionException("boom")) should be (Resume) 
+0

Spero che AKKA dia un nome a quei metodi in modo più intuitivo! – Mayumi

+0

"decider" è vago, ma non li vedo cambiare un nome (abbattendo la compatibilità all'indietro) a causa di un piccolo cambiamento di leggibilità. Oh bene –

0

Scommetto che il problema è in questo metodo:

def receive: Receive = { 
    case Msg => writer forward Msg 
    } 

"caso Msg" viene innescato da typeclass Msg, non con un'istanza della classe Msg. Qualcosa del genere dovrebbe funzionare:

def receive: Receive = { 
    case msg:Msg => writer forward msg 
    } 
+0

ho digitato sbagliato lo StackOverflow, che non è la mia domanda. Sto chiedendo come testare la gestione della strategia da bambino in su. – Mayumi