通过 system.actorOf 获得的 ActorRef 是否等于这个 actor 中的 self?
Does ActorRef obtained via system.actorOf equal to self inside this actor?
我设计了一个 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])
因此,在我的测试中,MyActor 中通过 self
获得的 ActorRef 似乎不等于通过 system.actorOf
获得的 ActorRef。有什么建议吗?
以下代码对我来说工作正常(测试通过):
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))
}
}
}
理想情况下,您发布的代码甚至不应在以下位置编译:
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
而发生特殊的魔法,我在下面写了普通老演员 class。
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
。所以你的程序没有问题。
我已经弄明白了。这是因为我在多个测试用例中使用了共享的 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))
....
}
}
}
无论如何,感谢所有人证明它对于单个测试用例运行良好。
我设计了一个 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])
因此,在我的测试中,MyActor 中通过 self
获得的 ActorRef 似乎不等于通过 system.actorOf
获得的 ActorRef。有什么建议吗?
以下代码对我来说工作正常(测试通过):
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))
}
}
}
理想情况下,您发布的代码甚至不应在以下位置编译:
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
而发生特殊的魔法,我在下面写了普通老演员 class。
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
。所以你的程序没有问题。
我已经弄明白了。这是因为我在多个测试用例中使用了共享的 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))
....
}
}
}
无论如何,感谢所有人证明它对于单个测试用例运行良好。