سؤال

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?

هل كانت مفيدة؟

المحلول 2

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.

نصائح أخرى

In my case this happened because my test class extended TestKit, but did not mix in ImplicitSender.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top