2014-09-22 5 views
5

Ich habe folgende:Akka Prüfaufsicht Fehlerbehandlung

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

Ich möchte oben Code Unit-Test im Grunde auf den ich versuche, sicher, wenn die Ausnahme auftritt, sind wir wieder aufnehmen noch die Verarbeitung, wie Sie unten sehen können. Das Problem ist, dass keine Ausnahme vom Supervisor abgefangen wird. Was ist der beste Weg, den unten stehenden Code zu testen?

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

Antwort

8

den Vorgesetzten des Verhalten zu testen, wenn ein Kind eine Ausnahme wirft Sie die supervisorStrategy testen müssen. Mit einem TestActorRef, haben Sie Zugriff auf die supervisorStrategy ‚s Teilfunktion erhalten und behaupten, dass eine gegebene Exception Ergebnisse in der erwarteten Directive

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

Ich hoffe AKKA nennt diese Methoden intuitiver! – Mayumi

+0

"Entscheider" ist vage, aber ich sehe nicht, dass sie einen Namen ändern (rückwärtskompatibel) wegen einer kleinen Lesbarkeitsänderung. Naja –

0

ich wette, das Problem bei dieser Methode ist:

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

"Fall Msg" wird von typeclass Nachricht ausgelöst, nicht durch eine Instanz der Klasse Msg. So etwas sollte funktionieren:

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

ich es in die falsche eingegeben Stackoverflow, das ist nicht meine Frage. Ich frage, wie man das Strategie-Handling von Kind an testen kann. – Mayumi