【发布时间】:2021-02-11 14:43:09
【问题描述】:
例如,我有两个演员——一个父演员和一个子演员。当父母收到一条消息时,它会产生与消息中指定的一样多的子actor。如何测试此功能?有没有办法模拟上下文或其他方法来检查演员是否正确创建且数量正确?
class ParentActor extends Actor {
case class CreateChildren(count: Int)
override def receive: Receive = {
case CreateChildren(count) => for (_ <- 0 until count) context.actorOf(Props[ChildActor])
}
}
class ChildActor extends Actor {
override def receive: Receive = {
case _ =>
}
}
更新:基于@Tim 回答的解决方案
更改的课程:
class ParentActor(childActorFactory: ChildActorFactory) extends Actor {
override def receive: Receive = {
case CreateChildren(count) => for (_ <- 0 until count) childActorFactory.create(context)
}
}
object ParentActor {
def props(childActorFactory: ChildActorFactory): Props = Props(new ParentActor(childActorFactory))
}
class ChildActorFactory {
def create(context: ActorContext): ActorRef = context.actorOf(Props[ChildActor])
}
测试:
"ParentActor" should {
"instantiate ten child actors" in {
val childrenCount = 10
val childActorFactory = mock[ChildActorFactory]
val parentActor = TestActorRef[ParentActor](ParentActor.props(childActorFactory))
parentActor ! CreateChildren(childrenCount)
Mockito.verify(childActorFactory, Mockito.times(childrenCount))
.create(parentActor.underlyingActor.context)
}
}
【问题讨论】:
-
为什么要创作这么多演员?你不想对其中之一做
context.become吗?您确定只想创建它们吗? -
@TomerShetah 单独的actor异步运行,允许更大的并行性,而使用
context.become是串行的。这也允许状态在子角色中本地化,而不是在父角色中集中。 -
@Tim,据我所知,在您将它们添加到上下文之前,它们根本不会被调用。远的例子,如果你在
ChildActor接收函数中添加:case s => println(s),并发送一个字符串到ParentActor,它不会被解析。 -
@TomerShetah 这是为支持有关演员创建和测试的特定问题而提供的伪代码,因此不要过多解读代码不完整的事实。
标签: scala unit-testing akka