I have a function which uses scheduleOnce
to schedule an event to happen some time in the future, and I want to write a test that checks that:
but I don't want the test to actually wait several minutes doing nothing.
How should I best test code that uses akka's Scheduler?
Here is an example of mocking out the scheduler as described by @lmm. In this example, we really test the full scheduling and handling of the action as two separate scenarios. The first testing that given some condition (a message of a certain type being received in my example) we will schedule a callback, and the second being the handling of the message that gets fired back to self when that timer goes off. The code is as follows:
object TimerExampleActor{
case object ClearState
case class ScheduleStateClearing(duration:FiniteDuration)
}
class TimerExampleActor extends Actor{
import TimerExampleActor._
var state:List[Int] = Nil
def receive = {
case ScheduleStateClearing(d) =>
scheduler.scheduleOnce(d, self, ClearState)(context.dispatcher)
case ClearState =>
state = Nil
}
def scheduler = context.system.scheduler
}
Then, using specs2 and mockito, my test case is as follows:
class TimerExampleActorTest extends Specification with Mockito with NoTimeConversions{
import TimerExampleActor._
implicit val system = ActorSystem("test")
trait testscope extends Scope{
val mockScheduler = mock[Scheduler]
val actor = TestActorRef(new TimerExampleActor{
override def scheduler = mockScheduler
})
}
"A request to schedule state clearing" should{
"schedule a callback for the message ClearState to self with the supplied duration" in new testscope{
val dur = 1.minute
actor ! ScheduleStateClearing(dur)
there was one(mockScheduler).scheduleOnce(dur, actor, ClearState)(actor.underlyingActor.context.dispatcher)
}
}
"A ClearState message received by the actor" should{
"clear the interval 'state' List" in new testscope{
actor.underlyingActor.state = List(1,2,3)
actor ! ClearState
actor.underlyingActor.state mustEqual Nil
}
}
}
You can see that when I create the actor instance under test I override the method I created to get me the instance of the scheduler, allowing me to return a mock. This is not the only way to go about testing something like this, but it certainly can be one option for you to consider.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With