Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

akka: how to test that an actor was stopped

I am wondering what the canonical way is of testing whether an actor has stopped in akka. Here is an example of how I am currently doing; I'm worried I'm over complicating it.

import akka.actor.{Terminated, Actor, Props, ActorSystem}
import akka.testkit.TestProbe

class MyActor extends Actor {
  import MyActor._
  override def receive: Receive = {
    case Stop => context.stop(self)
  }
}

object MyActor {
  def props = Props(new MyActor)
  case object Stop
}


object MyActorSpec {

  val system = ActorSystem()
  val myActor = system.actorOf(MyActor.props)
  val testProbe = TestProbe()

  case object MyActorStopped

  val watcher = system.actorOf(Props(new Actor {
    context.watch(myActor)
    override def receive: Actor.Receive = {
      case Terminated(`myActor`) => testProbe.ref ! MyActorStopped
    }
  }))

  myActor ! MyActor.Stop
  testProbe.expectMsg(MyActorStopped)
}
like image 887
Mullefa Avatar asked Dec 04 '15 09:12

Mullefa


People also ask

What happens when an actor fails in Akka?

When an actor throws an unexpected exception, a failure, while processing a message or during initialization, the actor will by default be stopped.

Can an Akka actor stop itself?

An actor can stop itself by returning. Behaviors. stopped as the next behavior. A child actor can be forced to stop after it finishes processing its current message by using the stop method of the ActorContext from the parent actor.

Can an Akka actor stop other actors?

In Akka, you can stop Actors by invoking the stop() method of either ActorContext or ActorSystem class. ActorContext is used to stop child actor and ActorSystem is used to stop top level Actor.

How do you shut down an actor?

In short, there are three ways to stop an actor: Stop() the actor: stops the actor immediately after it finishes processing the current message. Kill the actor: this throws an ActorKilledException which will be logged and handled. The actor will stop immediately after it finishes processing the current message.


1 Answers

You can get rid of the separate watcher actor, and just watch the target actor directly from the testProbe actor:

val testProbe = TestProbe()
testProbe watch myActor
myActor ! MyActor.Stop
testProbe.expectTerminated(myActor)

See here for the relevant section of the Akka testing docs.

like image 139
Shadowlands Avatar answered Sep 24 '22 13:09

Shadowlands