我设计的一个演员应该发送它的' actorRef到prestart上的另一个演员:
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。有什么建议吗?
答案 0 :(得分: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 :(得分: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
。所以你的程序没有任何问题。
答案 2 :(得分: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))
....
}
}
}
无论如何,多亏了所有证明对于单个测试用例它运行良好。