scala - Failing a scalatest when akka actor throws exception outside of the test thread -


i've had situation come , bite me few times i'm testing actor , actor throws exception unexpectedly (due bug), test still passes. of time exception in actor means whatever test verifying won't come out test fails, in rare cases that's not true. exception occurs in different thread test runner test runner knows nothing it.

one example when i'm using mock verify dependency gets called, , due mistake in actor code call unexpected method in mock. causes mock throw exception blows actor not test. can cause downstream tests fail mysteriously because of how actor blew up. example:

// using scala 2.10, akka 2.1.1, scalatest 1.9.1, easymock 3.1 // (funspec , 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 when receives 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" passes, downstream "ok actor" fails reason don't understand... exception:

cannot reserve actor name '$$b': terminated java.lang.illegalstateexception: cannot reserve actor name '$$b': terminated @       akka.actor.dungeon.childrencontainer$terminatedchildrencontainer$.reserve(childrencontainer.scala:86) @ akka.actor.dungeon.children$class.reservechild(children.scala:78) @ akka.actor.actorcell.reservechild(actorcell.scala:306) @ akka.testkit.testactorref.<init>(testactorref.scala:29) 

so, can see ways of catching sort of thing examining logger output in aftereach handlers. doable, although little complicated in cases expect exception , that's i'm trying test. there more direct way of handling , making test fail?

addendum: have looked @ testeventlistener , suspect there's maybe there help, can't see it. documentation find using check expected exceptions, not unexpected ones.

thinking in actors there solution: failures travel supervisor, perfect place catch them , feed them test procedure:

val failures = testprobe() val props = ... // description actor under test val failureparent = system.actorof(props(new actor {   val child = context.actorof(props, "child")   override val supervisorstrategy = oneforonestrategy() {     case f => failures.ref ! f; stop // or whichever directive appropriate   }   def receive = {     case msg => child forward msg   } })) 

you can send actor under test sending failureparent , failures—expected or not—go failures probe inspection.


Comments

Popular posts from this blog

How to remove text and logo OR add Overflow on Android ActionBar using AppCompat on API 8? -

html - How to style widget with post count different than without post count -

url rewriting - How to redirect a http POST with urlrewritefilter -