I have following:
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)
}
}
I want to unit test above code basically I am trying to make sure when the exception occurs, we are still resuming the processing as you can see below. The problem is that no exception is caught by the supervisor. What is the best way to test the code below?
"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))
}
To test the supervisor's behaviour when a child throws an exception you must test the supervisorStrategy
. Using a TestActorRef
, you can get access to the supervisorStrategy
's partial function and assert that a given Exception
results in the expected Directive
val supervisor = TestActorRef[Supervisor](Props(new Supervisor(dataProvider)))
val strategy = supervisor.underlyingActor.supervisorStrategy.decider
strategy(ConnectionException("boom")) should be (Resume)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With