I've got the following test spec:
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)
}
And following actor:
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)
}
}
}
Test case is always passing because orginalSender
in actor class is deadLetters
, not reference to test sender.
Here is the log output after test is run:
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'.
Why is this happening?
In my case this happened because my test class extended TestKit
, but did not mix in ImplicitSender
.
The only possibility that I can see is that you have another implicit ActorRef
in scope in your test procedure, leading to an ambiguous implicit argument which then means that none of them is picked up.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With