Akka Test Manager Error Handling

I have the 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 a unit test above the code, basically I'm trying to make sure that when an exception occurs, we will resume processing anyway, as you can see below. The problem is that the supervisor does not rule out an exception. What is the best way to check 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)) } 
+5
source share
2 answers

To check the behavior of a supervisor when a child throws an exception, you should check supervisorStrategy . Using TestActorRef , you can access the partial supervisorStrategy function and claim that this 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) 
+9
source

I am sure that the problem lies in this method:

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

"case Msg" is started using typeclass Msg, not an instance of the Msg class. Something like this should work:

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

Source: https://habr.com/ru/post/1203144/


All Articles