2014-09-22 11 views
5

Mam następujący:Akka błąd testowania kierownik obsługi

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

Chcę testów jednostkowych powyższym kodzie zasadzie staram się upewnić, gdy wystąpi wyjątek, jesteśmy nadal wznowienie przetwarzania, jak widać poniżej. Problem polega na tym, że nadzorca nie przyjmuje żadnego wyjątku. Jaki jest najlepszy sposób na przetestowanie poniższego kodu?

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

Odpowiedz

8

Aby przetestować zachowanie przełożonego, gdy dziecko zgłasza wyjątek należy przetestować supervisorStrategy. Korzystanie z TestActorRef, można uzyskać dostęp do częściowego funkcji supervisorStrategy „s i twierdzić, że dana Exception wyników w oczekiwanym Directive

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

Mam nadzieję, że AKKA nadaje te metody w bardziej intuicyjny sposób! – Mayumi

+0

"Zdecydowanie" jest niejasne, ale nie widzę, żeby zmieniały nazwę (zrywając kompatybilność wsteczną) ze względu na niewielką zmianę czytelności. No cóż –

0

Założę się, że problem jest w tym sposobie:

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

"przypadek Msg" jest wyzwalane przez typeclass MSG, nie przez instancję klasy Centr. Coś jak to powinno działać:

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

Wpisałem to źle na stackoverflow, to nie moja sprawa. Pytam, jak przetestować obsługę strategii od dziecka. – Mayumi