我在PersistentActor中使用context.become时有一种奇怪的行为(不确定持久性是否与问题的原因有关)。我的代码类似于:
class MyActor extends PersistentActor {
import context._
// Messages
case object Start
case object Ready
case object MessageX
// Events
case object Started
def recieveRecover: Receive = { /* Not relevant, I think */}
def receiveCommand: Receive = idle
def idle: Receive = {
case Start =>
persist(Started) { _ =>
sender() ! Ready
become(ready)
}
}
def ready: Receive = {
case MessageX => doSomething()
}
}
我在同一个MyActorSpec文件中有两个测试。第一个只是测试空闲'状态和第二个测试准备好的'状态:
"Test A" in {
val actorRef = system.actorOf( MyActor.props(), "test-A-actor" )
actorRef ! Start
expectMsg(Ready)
}
"Test B" in {
val actorRef = system.actorOf( MyActor.props(), "test-B-actor" )
actorRef ! Start
expectMsg(Ready) /* It fails here because for some reason the actorRef
was created with its 'receiveCommand' block equal to
the 'ready' block and not equal to the 'idle' block as its suppossed to.
So it timeouts here waiting for the message which is not handled in
the 'ready' block */
actorRef ! MessageX
testSomethingAboutTheMessageX()
}
如果我运行两个测试,第一个测试成功,但第二个测试无法等待就绪消息(如第二个测试中的注释中所述)。如果我只运行第二次测试。所以,我不确定在定义演员时我是否做错了。
更新:我尝试按照建议移除Started
事件(persist(Started)
部分)的持久性,测试按预期工作(两个actor都是在idle
状态下创建的)。所以,正在发生的事情是第一个actor实例上的事件被持久化,然后第二个actor实例正在重放它们,这是因为使用相同的persistenceId
创建了actor实例(DOH) !)。因此,使测试独立的方法只是用不同的persistenceId
实例化每个actor。
答案 0 :(得分:2)
发生的事情是第一个actor实例上的事件被持久化,然后第二个actor实例正在重放它们,这是因为使用相同的persistenceId
创建了actor实例( DOH!)。因此,使测试独立的方法只是用不同的persistenceId
实例化每个actor。
答案 1 :(得分:0)
它可能是由Specs2同时运行所有测试引起的,因为它的'sequential'参数的默认值为'false'。
要强制所有测试一个接一个地执行,请在规范的顶部指定顺序,如下所示:
class MyActorSpec extends Specification {
// Run the tests sequentially
sequential
"MyActor" should {
"Test A" in {
// test goes here
}
"Test B" in {
// test goes here
}
}
}
看一看 http://etorreborre.github.io/specs2/guide/org.specs2.guide.Runners.html 详情。