2014-11-13 14 views
6

Mam funkcja, która wykorzystuje scheduleOnce zaplanować zdarzenie się zdarzyć jakiś czas w przyszłości, i chcę napisać test, który sprawdza, że:Testowanie zdarzenia timera w Akka

  • zdarzenie rzeczywiście zaplanowane
  • to było zaplanowane w odpowiednim czasie
  • system zachowuje się zgodnie z oczekiwaniami, gdy zdarzenie ostatecznie wyzwala

ale nie chcę test faktycznie poczekać kilka minut zrobić nic nie robić.

Jak najlepiej przetestować kod korzystający z programu planującego akka?

+0

Co właściwie próbujesz przetestować? Akka to popularny, dobrze przetestowany kod - myślę, że możesz być dość pewny, że jego harmonogram działa zgodnie z opisem. Jeśli chcesz przetestować, czy zdarzenie jest zaplanowane i system robi to, co należy, gdy zaplanowane zdarzenie się wydarzy, to może wyśmiewać program planujący za pomocą tego, który zostanie wywołany, gdy twój kod testowy to powie? – lmm

+0

To by działało dobrze, nie chcę testować samej Akki. Czy masz przykład kodu, który wyśmiewa harmonogram w taki sposób? – nornagon

+0

To jest stary temat, ale znalazłem [to] (https://github.com/miguno/akka-mock-scheduler) lib, jeszcze go nie wypróbowałem, ale wygląda na to, że może pomóc. – lockwobr

Odpowiedz

0

Ustaw parametr harmonogramu na czas. W teście użyj krótszego czasu niż w zwykłym kodzie.

... Albo podczas testowania można mieszać w specjalną cechę, która modyfikuje swoją klasę, ile potrzeba (skraca czas oczekiwania).

4

Oto przykład szydząc z harmonogramu w sposób opisany przez @lmm. W tym przykładzie naprawdę testujemy pełne planowanie i obsługę akcji jako dwóch oddzielnych scenariuszy. Pierwsze testowanie z pewnymi warunkami (wiadomość o pewnym typie odbierana w moim przykładzie) zaplanujemy oddzwanianie, a drugim będzie obsługa wiadomości, która zostanie odpalona do siebie, gdy ten zegar się wyłączy. Kod jest w następujący sposób:

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 
} 

Następnie, używając specs2 i Mockito, mój przypadek testowy jest następujący:

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 
    } 
    } 
} 

Widać, że gdy tworzę instancję aktor badanego I zastąpić metodę Stworzyłem dla mnie instancję programu planującego, pozwalając mi zwrócić próbę. Nie jest to jedyny sposób testowania czegoś podobnego, ale z pewnością może być jedną z opcji do rozważenia.

+0

testuje, że gdy upłynie termin modułu harmonogramu, wysyłana jest wiadomość ClearState? – Jas