【发布时间】:2015-11-06 01:03:17
【问题描述】:
各位程序员和敬佩的大师们,
我有一个实现 FSM 的参与者,它需要在特定状态(忙碌)由其主管重新启动时对某些消息抛出 IOException .
摘录:
case class ExceptionResonse(errorCode: Int)
when(Busy) {
case ExceptionResponse(errorCode) =>
throw new IOException(s"Request failed with error code $errorCode")
}
我正在尝试通过使用TestActorRef 并在期望接收时直接调用receive 来测试该行为以抛出IOException。
case class WhenInStateBusy() extends TestKit(ActorSystem()) with After {
val myTestFSMRef = TestFSMRef(MyFSM.props)
...
def prepare: Result = {
// prepares tested actor by going through an initialization sequence
// including 'expectMsgPfs' for several messages sent from the tested FSM
// most of my test cases depend on the correctness of that initialization sequence
// finishing with state busy
myTestFSMRef.setState(Busy)
awaitCond(
myTestFSMRef.stateName == Busy,
maxDelay,
interval,
s"Actor must be in State 'Busy' to proceed, but is ${myTestFSMRef.stateName}"
)
success
}
def testCase = this {
prepare and {
myTestFSMRef.receive(ExceptionResponse(testedCode)) must throwAn[IOException]
}
}
}
注意:初始化序列确保测试的 FSM 已完全初始化并已设置其内部可变状态。状态 Busy 只能在参与者收到某种消息时才能离开,在我的测试设置中必须由测试用例提供该消息,所以我很确定 FSM 处于正确的状态。
现在,在我的 Jenkins 服务器(Ubuntu 14.10)上,这个测试用例在 20 次尝试中大约有 1 次失败(-> 没有抛出异常)。但是,在我的开发机器(Mac Os X 10.10.4)上,我无法重现该错误。所以调试器对我没有帮助。
测试按顺序运行,在每个示例之后,测试系统都会关闭。
- Java 版本 1.7.0_71
- Scala 版本 2.11.4
- Akka 版本 2.3.6
- Specs2 版本 2.3.13
谁能解释为什么有时调用myTestActorRef.receive(ExceptionResponse(testedCode)) 不会导致Exception?
【问题讨论】:
-
您没有显示
myTestActorRef的创建位置。是myTestFSMRef的错字还是两个不同的对象? -
@mattinbits 是的,这是一个错字,已解决问题
-
您对 awaitCond 的看法是对的,我正在查看 Java API。不过,AssertException 会让您的测试失败,对吧?
-
是的,AssertionException 使测试失败。
-
我在this question 的答案变体中找到了解决我的问题的方法。但是,我仍然不明白为什么这不起作用。
标签: scala akka akka-testkit