Niepowodzenie skalowania, gdy akka actor rzuca wyjątek poza wątkiem testowym

Miałem sytuację, w której wpadłem i ugryź mnie kilka razy, kiedy testuję Aktora, a Aktor niespodziewanie rzuca wyjątek (z powodu błędu), ale test wciąż mija. Teraz wyjątek w aktorze oznacza, że ​​cokolwiek test sprawdza, nie wyjdzie poprawnie, więc test nie powiedzie się, ale w rzadkich przypadkach nie jest to prawdą. Wyjątek występuje w innym wątku niż biegacz testowy, więc biegacz testowy nic o tym nie wie.

Jednym z przykładów jest sytuacja, w której używam makiety w celu sprawdzenia, czy została wywołana zależność, a ze względu na błąd w kodzie aktora w makiecie nazywam nieoczekiwaną metodę. To powoduje, że próba rzuca wyjątek, który wysadza w powietrze aktora, ale nie test. Czasami może to nawet powodowaćw dół rzeki testy, które w tajemniczy sposób zawiodły z powodu wybuchu Aktora. Na przykład:

// using scala 2.10, akka 2.1.1, scalatest 1.9.1, easymock 3.1
// (FunSpec and TestKit)
class SomeAPI {
  def foo(x: String) = println(x)
  def bar(y: String) = println(y)
}

class SomeActor(someApi: SomeAPI) extends Actor {
  def receive = {
    case x:String  =>
      someApi.foo(x)
      someApi.bar(x)
  }
}

describe("problem example") {
  it("calls foo only when it receives a message") {
    val mockAPI = mock[SomeAPI]
    val ref = TestActorRef(new SomeActor(mockAPI))

    expecting {
      mockAPI.foo("Hi").once()
    }

    whenExecuting(mockAPI) {
      ref.tell("Hi", testActor)
    }
  }

  it("ok actor") {
    val ref = TestActorRef(new Actor {
      def receive = {
        case "Hi"  => sender ! "Hello"
      }
    })
    ref.tell("Hi", testActor)
    expectMsg("Hello")
  }
}

„problemExample” przechodzi, ale później „ok actor” kończy się niepowodzeniem z jakiegoś powodu, którego tak naprawdę nie rozumiem ... z tym wyjątkiem:

cannot reserve actor name '$b': already terminated
java.lang.IllegalStateException: cannot reserve actor name '$b': already terminated
at       akka.actor.dungeon.ChildrenContainer$TerminatedChildrenContainer$.reserve(ChildrenContainer.scala:86)
at akka.actor.dungeon.Children$class.reserveChild(Children.scala:78)
at akka.actor.ActorCell.reserveChild(ActorCell.scala:306)
at akka.testkit.TestActorRef.<init>(TestActorRef.scala:29)

Widzę więc sposoby łapania tego rodzaju rzeczy, badając dane wyjściowe rejestratora w programach obsługi AfterEach. Zdecydowanie wykonalne, choć trochę skomplikowane w przypadkach, w których oczekuję wyjątku i to właśnie próbuję przetestować. Ale czy istnieje bardziej bezpośredni sposób radzenia sobie z tym i spowodowania niepowodzenia testu?

Dodatek: Spojrzałem na TestEventListener i podejrzewam, że może coś tam pomoże, ale nie widzę tego. Jedyną dokumentacją, jaką mogłem znaleźć, było użycie jej do sprawdzenia oczekiwanych wyjątków, a nie niespodziewanych.

questionAnswers(3)

yourAnswerToTheQuestion