我有以下测试规范:
class SiteCheckerSpec extends TestKit(ActorSystem("testSystem"))
with ImplicitSender
with BeforeAndAfterAll
with Matchers
with WordSpecLike {
val sites = List(
"www.google.com",
"www.apple.com",
"www.gazeta.pl"
)
"Tested SiteChecker actor" must {
"not receive message" in {
val testedActor = system.actorOf(Props(new SiteChecker(sites.size) with TestActorContextCreationSupport {
override def actorRefFactory = system
}))
testedActor ! SiteChecker.CheckSitesTitles(sites)
expectNoMsg()
}
}
override protected def afterAll(): Unit = TestKit.shutdownActorSystem(system)
}
跟随演员:
class SiteChecker(workersCount: Int) extends Actor
with ActorLogging
with ActorContextCreationSupport {
val resultMap = mutable.HashMap.empty[String, String]
var originalSender: Option[ActorRef] = None
val workers = (
for (i <- 1 to workersCount) yield createChildren(SiteCheckerWorker.props())
).toList
def actorRefFactory: ActorRefFactory = context
override def receive: Actor.Receive = {
case SiteChecker.CheckSitesTitles(sites) =>
log.info(s"Sites to check $sites")
println(sender)
originalSender = Some(sender)
workers.zip(sites).foreach(
t => t._1 ! SiteCheckerWorker.CheckSiteTitle(t._2)
)
case SiteCheckerWorker.SiteTitle(site, title) =>
log.info(s"Obtained title $title for site $site")
resultMap += (site -> title)
if (resultMap.size == workers.size) {
originalSender.get ! SiteChecker.SitesTitles(resultMap.toMap)
context.children.foreach(context.stop)
}
}
}
测试用例总是在传递,因为actor类中的orginalSender
是deadLetters
,而不是对测试发送者的引用。
以下是测试运行后的日志输出:
Actor[akka://testSystem/deadLetters]
[INFO] [02/13/2014 18:53:59.150] [testSystem-akka.actor.default-dispatcher-2] [akka://testSystem/user/$a] Sites to check List(www.google.com, www.apple.com, www.gazeta.pl)
[INFO] [02/13/2014 18:53:59.154] [testSystem-akka.actor.default-dispatcher-3] [akka://testSystem/user/$a] Obtained title www.gazeta.pl for site www.gazeta.pl
[INFO] [02/13/2014 18:53:59.157] [testSystem-akka.actor.default-dispatcher-3] [akka://testSystem/user/$a] Obtained title www.google.com for site www.google.com
[INFO] [02/13/2014 18:53:59.158] [testSystem-akka.actor.default-dispatcher-5] [akka://testSystem/user/$a] Obtained title www.apple.com for site www.apple.com
[INFO] [02/13/2014 18:53:59.163] [testSystem-akka.actor.default-dispatcher-4] [akka://testSystem/deadLetters] Message [actor.site.SiteChecker$SitesTitles] from Actor[akka://testSystem/user/$a#735871082] to Actor[akka://testSystem/deadLetters] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'.
为什么会这样?
答案 0 :(得分:9)
在我的情况下发生这种情况是因为我的测试类扩展了TestKit
,但没有混合ImplicitSender
。
答案 1 :(得分:3)
我能看到的唯一可能性是你的测试程序中有另一个implicit ActorRef
范围,导致一个模糊的隐式参数,这意味着它们都没有被选中。