2

我设计了一个actor,它应该在预启动时将它的actorRef发送给另一个actor:

class MyActor(notifier: ActorRef) extends Actor {
  override def preStart(): Unit = {
    notifier ! Register(self)
  }
  ...
}

case class Register(actor: ActorRef)

然后我为这个 Actor 编写了一个规范:

class MyActorSpec extends TestKit(ActorSystem("MyActorSpec"))
                  with ImplicitSender 
                  with WordSpecLike 
                  with Matchers 
                  with BeforeAndAfterAll {

  "MyActor" should {
     val notifier = TestProbe()
     "register itself in notifier" in {
         val myActor = system.actorOf(Props(classOf[MyActor], notifier.ref))
         notifier.expectMsg(Register(myActor))
     }
  }
}

当我运行测试时,它失败并显示以下消息:assertion failed: expected Register(Actor[akka://MyActorSpec/user/$b#1849780829]), found Register(Actor[akka://MyActorSpec/user/$a#1143150267])

因此,似乎通过 MyActorself内部获得的 ActorRef 不等于system.actorOf在我的测试中获得的 ActorRef 。有什么建议么?

4

3 回答 3

1

以下代码对我来说工作得很好(测试通过):

class MyActor(notifier: ActorRef) extends Actor {
  override def preStart(): Unit = {
    notifier ! Register(self)
  }

  override def receive: Receive = {
    case _ =>
  }
}

case class Register(actor: ActorRef)

class MyActorSpec extends TestKit(ActorSystem("MyActorSpec")) with ImplicitSender with WordSpecLike with Matchers with BeforeAndAfterAll {
  "MyActor" should {
    val notifier = TestProbe()
    "register itself in notifier" in {
      val myActor = system.actorOf(Props(new MyActor(notifier.ref)))
      notifier.expectMsg(Register(myActor))
    }
  }
}
于 2015-07-13T13:42:57.753 回答
1

您理想情况下发布的代码甚至不应该在以下位置编译:

val myActor = system.actorOf(Props(classOf[MyActor], notifier))

因为构造函数期望一个ActorRef我们没有传递的。但纠正它,它的工作原理:

class MyActorSpec extends TestKit(ActorSystem("MyActorSpec"))
with ImplicitSender
with WordSpecLike
with Matchers
with BeforeAndAfterAll {

  "MyActor" should {
    val notifier = TestProbe()
    "register itself in notifier" in {
      val myActor = system.actorOf(Props(classOf[MyActor], notifier.ref))
      notifier.expectMsg(Register(myActor))
    }
  }
}

有一秒钟,为了确保不会因为 发生特殊的魔法ActorProbe,我在下面写了普通的老演员类。

object Prac {
  def main(args: Array[String]) {
    val system = ActorSystem("HelloSystem")
    val myActor = system.actorOf(Props(classOf[MainActor]))
  }

}

class MyActor(notifier: ActorRef) extends Actor {

  override def preStart(): Unit = {
    notifier ! Register(self)
  }

  override def receive: Receive = {
    case x => println("My Actor ->"+x)
  }
}

case class Register(actor: ActorRef)

class MainActor extends Actor{

  val actor = context.actorOf(Props(classOf[MyActor], self))

  override def receive = {
    case Register(x) =>
      println(actor == x)
      context.system.shutdown()
  }
}

它打印出来true。所以你的程序没有问题。

于 2015-07-13T13:46:15.267 回答
0

我已经想通了。这是因为我在几个测试用例中使用了共享 TestProbe,在这些测试用例中我创建了不同的 MyActor 实例。

class MyActorSpec extends TestKit(ActorSystem("MyActorSpec"))
                  with ImplicitSender 
                  with WordSpecLike 
                  with Matchers 
                  with BeforeAndAfterAll {

  "MyActor" should {
     val notifier = TestProbe()
     "register itself in notifier" in {
         val myActor = system.actorOf(Props(classOf[MyActor], notifier.ref))
         notifier.expectMsg(Register(myActor))
     }
     "do some useful work" in {
         val myActor = system.actorOf(Props(classOf[MyActor], notifier.ref))
         ....
     }
  }
}

相反,为每个测试用例使用新的 TestProbe 实例会有所帮助。

class MyActorSpec extends TestKit(ActorSystem("MyActorSpec"))
                  with ImplicitSender 
                  with WordSpecLike 
                  with Matchers 
                  with BeforeAndAfterAll {

  "MyActor" should {
     "register itself in notifier" in {
         val notifier = TestProbe()
         val myActor = system.actorOf(Props(classOf[MyActor], notifier.ref))
         notifier.expectMsg(Register(myActor))
     }
     "do some useful work" in {
         val notifier = TestProbe()
         val myActor = system.actorOf(Props(classOf[MyActor], notifier.ref))
         ....
     }
  }
}

无论如何,感谢所有人证明对于单个测试用例它运行良好。

于 2015-07-14T05:39:20.997 回答