Reputation: 7940
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))
}
Upvotes: 8
Views: 2024
Reputation: 5618
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)
Upvotes: 13
Reputation: 2938
I bet the problem is in this method:
def receive: Receive = {
case Msg => writer forward Msg
}
"case Msg" is triggered by typeclass Msg, not by an instance of class Msg. Something like this should work:
def receive: Receive = {
case msg:Msg => writer forward msg
}
Upvotes: 0