用期货测试akka FSM

时间:2014-03-20 15:03:25

标签: intellij-idea akka fsm

我有一个在州内使用期货的akka​​ FSM演员。例如:

when(StateA) {
  case Event(str: String, _) =>
    if (str == "ping") {
      Future("await-ping").pipeTo(self)(sender)
      goto(AwaitStateA)
    } else {
      stay() replying "stay-ping"
    }
}

when(AwaitStateA) {
  case Event(str: String, _) =>
  goto(StateA) replying str
}

使用akka testkit测试上面的actor:

val adaptation: TestFSMRef[State, Data, _ <: Actor]

"Switch between states A" must {
  "should return `await-ping`" in {
    adaptation ! "ping"
    expectMsg("await-ping")
    adaptation.stateName should be(StateA)
  }
  "should return `stay-ping`" in {
    adaptation ! "pong"
    expectMsg("stay-ping")
    adaptation.stateName should be(StateA)
  }
}

您可以在github上找到的测试的完整代码:https://github.com/azhur/fsmtest

问题是测试随机失败(有时它们都通过了)。 测试中出现失败“应该返回await-ping” - &gt; “AwaitStateA不等于StateA”。 请帮忙找出我弄错的地方。

我尝试从命令行和IDE(Intellij IDEA)运行测试。结果是一样的。当我单独运行每个测试时,很难发现故障。

1 个答案:

答案 0 :(得分:2)

未来正在全局ExecutionContext(您已导入)上运行,并且它与TestFSMRef使用的调用线程调度程序之间存在竞争。

我不会在这里使用TestFSMRef。如果验证状态转换很重要,则可以使用FSM转换侦听器。像这样:

val adaptation: ActorRef = system.actorOf(Props[FsmSwitcher1])

"should return `await-ping`" in {
  val transitionListener = TestProbe()
  adaptation ! SubscribeTransitionCallBack(transitionListener.ref)
  transitionListener.expectMsg(CurrentState(adaptation, StateA))
  adaptation ! "ping"
  expectMsg("await-ping")
  transitionListener.expectMsg(Transition(adaptation, StateA, AwaitStateA))
  transitionListener.expectMsg(Transition(adaptation, AwaitStateA, StateA))
}