2015-07-13 55 views
2

我設計應該派遣actorRef另一個演員在啓動前的演員:ActorRef是否通過system.actorOf獲得,等於這個actor中的self?

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

因此,似乎在MyActor中通過self獲取的ActorRef不等於在我的測試中通過system.actorOf獲得的ActorRef。有什麼建議麼?由於構造函數需要一個ActorRef

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

回答

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)) 
     .... 
    } 
    } 
} 

無論如何,多虧了所有的證明,單個測試案例它運作良好。

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

您發佈非常不應該,即使在編譯代碼我們沒有通過。但修正它,它的工作原理:

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,我已經糾正它。 –