Hap*_*r86 10 scala akka scalatest testkit
我正在尝试编写一个测试,以验证我的演员下面是创建heartBeatExpireWorker和heartBeatAccepter,但我不知道该怎么做.
首先,我想我可以使用Mockhito模拟或间谍代替上下文然后验证我调用了actorOf,但我无法找到一种方法来注入上下文而不破坏Akka测试框架.
然后,我想我可以向工人发送识别信息以验证它们是否存在.但是我发现这不起作用,因为Akka TestKit似乎没有创建被测试演员的儿童演员.它只能接受可以代表相邻参与者的Testprobes.
class HeartBeatPumpWorker(chatService: ChatService, target: HeartBeatMessageCmd) extends Actor with ActorLogging with
WorkersReference {
val heartBeatInterval = chatService.getHeartBeatInterval
val tick = context.system.scheduler.schedule(0 millis, heartBeatInterval millis, self, SendHeartBeat(target))
override def postStop() = tick.cancel()
def receive = {
case SendHeartBeat(command: HeartBeatMessageCmd) =>
log.debug("Sending heartbeat")
//Send heartbeat to GWT
val userTarget = NetworkWorker.buildEventUserTarget(command.getEventCode, command.getUser)
val uuid: String = UUID.randomUUID().toString
val freshCommand = new HeartBeatMessageCmd(command.getUser, command.getEventCode, uuid, command.getUserSession)
networkWorker ! NetworkBroadcast(userTarget, freshCommand)
val heartBeatId: String = freshCommand.getUuid
//create expirer
val heartBeatExpireWorkerRef = context.actorOf(HeartBeatExpireWorker.props(chatService, freshCommand),
HeartBeatExpireWorker.name(heartBeatId))
val heartBeatAccepterRef = context
.actorOf(HeartBeatAcceptWorker.props(chatService, freshCommand), HeartBeatAcceptWorker.name(heartBeatId))
//record heartbeat
chatService.saveSentHeartbeat(heartBeatId, freshCommand.getUserSession, freshCommand.getEventCode,
freshCommand.getUser,
freshCommand.getTimeCmdGenerated)
case _ =>
log.error("Pumper received unknown message. This shouldn't happen " + sender.path.toString)
self ! PoisonPill
}
}
object HeartBeatPumpWorker {
def name(eventCode: String, user: String, sessionId: String) = f"HeartBeatPumpWorker-$eventCode-$user-$sessionId"
def path(eventCode: String, user: String, sessionId: String) : String = {
EventWorker.Path + "/" + name(eventCode, user, sessionId)
}
def props(chatService: ChatService, heartBeatMsgCmd: HeartBeatMessageCmd) = {
Props(classOf[HeartBeatPumpWorker], chatService, heartBeatMsgCmd)
}
}
Run Code Online (Sandbox Code Playgroud)
And*_*ejs 16
我目前使用的技术是拦截actor创建并创建TestProbes.在我的演员中,我混合了一个单独的ActorMaker特征:
trait ActorMaker { this: Actor =>
def makeActor(props: Props) = context.actorOf(props)
}
Run Code Online (Sandbox Code Playgroud)
并使用它MyActor extends Actor with ActorMaker而不是context.actorOf.
对于测试我有一个TestProbeMaker捕获所有创建的actor及其道具:
trait TestProbeMaker { this: Actor =>
val probes = ListBuffer.empty[(Props, TestProbe)]
def makeActor(props: Props) = { val probe = TestProbe()
probes += (props -> probe)
probe.ref
}
}
Run Code Online (Sandbox Code Playgroud)
我在测试期间将它混合在一起
val actorUnderTest = TestActorRef(Props(new MyActor with TestProbeMaker))
Run Code Online (Sandbox Code Playgroud)
这样我就可以确切地断言创建了什么演员.我也可以使用probe.expectMsg断言消息被发送给那些创建的actor.
要访问探针使用 actorUnderTest.underlyingActor.asInstanceOf[TestProbeMaker]
在父级的构造函数中注入Props子级(例如) 。通过任何你想要的测试。让父级通过提供的实例化子级。与孩子们互动。最后一部分取决于您的数据流。例如,如果父级阻止您与子级接触,但将消息委托给他们,则将消息发送给父级。如果孩子们互相交谈,请使用测试探针或类似的东西。HeartBeatAcceptWorker.propsHeartBeatPumpWorkerPropsProps