2015-07-13 2 views
2

Я разработал актер, который должен отправить его actorRef другого актеру на предпусковом:Имеет ли ActorRef файл system.actorOf, равный себе внутри этого актера?

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

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(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])

Таким образом, кажется, что ActorRef получается через self внутри MyActor не равна ActorRef, полученный с помощью system.actorOf в моем тесте. Какие-либо предложения?

ответ

0

Я понял это. Это связано с тем, что я использовал общий тестовый пакет в нескольких тестовых случаях, в которых я создаю разные экземпляры 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)) 
     .... 
    } 
    } 
} 

В любом случае, спасибо всем за доказательство того, что для одного тестового случая он работает хорошо.

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)) 
    } 
    } 
} 
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. Поэтому в вашей программе нет ничего плохого.

+0

Да, в моем вопросе было действительно notifier.ref, я исправил его. –