测试将Stash与TestActorRef混合的Akka演员 [英] Testing Akka actors that mixin Stash with TestActorRef

查看:80
本文介绍了测试将Stash与TestActorRef混合的Akka演员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个扩展了Stash的actor的问题,当在一个简单的ActorSystem中用actorOf实例化它时,它可以很好地工作。现在,我实际上想在我的隐藏演员在程序中使用它们之前为其编写一些测试。但是我无法找出在测试套件中与此演员一起使用TestActorRef的方法。

I'm running into a problem with an actor that extends Stash and which works perfectly fine when instantiating it with actorOf in a simple ActorSystem. Now I would actually like to write some tests for my stashing actors before using them in my program. But I cannot figure out a way to use an TestActorRef with this actor in my test suite.

有效的代码如下:

import akka.actor.{Stash, Actor, ActorSystem, Props}
import com.typesafe.config.ConfigFactory

object StashTest {
  val config = ConfigFactory.parseString(
    """
      |akka.actor.default-mailbox {
      | mailbox-type = "akka.dispatch.UnboundedDequeBasedMailbox"
      |}
    """.stripMargin)
}

class StashTestActor extends Stash {

  def receive: Actor.Receive = {
    case "unstash" =>
      unstashAll()
      context become print
    case msg => stash()
  }

  def print: Actor.Receive = {
    case msg => println(s"Unstashed message: $msg")
  }
}

val system = ActorSystem("stashSystem", StashTest.config)
val ref = system.actorOf(Props[StashTestActor])

ref ! "stash me"
ref ! "blah"
ref ! "unstash"

哪些印刷品

Unstashed message: stash me

Unstashed message: blah

但是,如果我尝试为此演员编写WordSpec测试,则会给我留下一些令人讨厌的异常,我无法弄清楚他们希望我在我的代码中进行什么更改。

But if I try to write a WordSpec test for this actor, it leaves me with some nasty exceptions I can't figure out what they would like me to change in my code.

测试类如下

import akka.testkit.{TestActorRef, TestKit}
import akka.actor.{Stash, Actor, ActorSystem}
import org.scalatest.{WordSpecLike, MustMatchers}
import com.typesafe.config.ConfigFactory


class StashTestActor extends Stash {

  def receive: Actor.Receive = {
    case "unstash" =>
      unstashAll()
      context become print
    case msg => stash()
  }

  def print: Actor.Receive = {
    case msg => println(s"Unstashed message: $msg")
  }
}


class StashTest extends TestKit(ActorSystem("testSystem", StashTest.config))
with WordSpecLike
with MustMatchers {

  "A simple stashing actor" must {
    val actorRef = TestActorRef[StashTestActor]

    "stash messages" in {
      actorRef ! "stash me!"
    }

    "unstash all messages" in {
      actorRef ! "unstash"
    }
  }
}

object StashTest {
  val config = ConfigFactory.parseString(
    """
      |akka.actor.default-mailbox {
      | mailbox-type = "akka.dispatch.UnboundedDequeBasedMailbox"
      |}
    """.stripMargin)
}

运行测试时,我得到以下实例化TestActorRef实例期间引发的异常。

When running the test, I get following exceptions that are thrown during the instantiation of the TestActorRef.

[ERROR] [08/20/2013 14:19:40.765] [testSystem-akka.actor.default-dispatcher-3] [akka://testSystem/user/$$a] Could not instantiate Actor
Make sure Actor is NOT defined inside a class/trait,
if so put it outside the class/trait, f.e. in a companion object,
OR try to change: 'actorOf(Props[MyActor]' to 'actorOf(Props(new MyActor)'.
akka.actor.ActorInitializationException: exception during creation
    at akka.actor.ActorInitializationException$.apply(Actor.scala:218)
    at akka.actor.ActorCell.create(ActorCell.scala:578)
    at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:425)
    at akka.actor.ActorCell.systemInvoke(ActorCell.scala:447)
    at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:262)
    at akka.testkit.CallingThreadDispatcher.process$1(CallingThreadDispatcher.scala:244)
    at akka.testkit.CallingThreadDispatcher.runQueue(CallingThreadDispatcher.scala:284)
    at akka.testkit.CallingThreadDispatcher.register(CallingThreadDispatcher.scala:153)
    at akka.dispatch.MessageDispatcher.attach(AbstractDispatcher.scala:133)
    at akka.actor.dungeon.Dispatch$class.start(Dispatch.scala:84)
    at akka.actor.ActorCell.start(ActorCell.scala:338)
    at akka.testkit.TestActorRef.<init>(TestActorRef.scala:50)
    at akka.testkit.TestActorRef$.apply(TestActorRef.scala:141)
    at akka.testkit.TestActorRef$.apply(TestActorRef.scala:137)
    at akka.testkit.TestActorRef$.apply(TestActorRef.scala:146)
    at akka.testkit.TestActorRef$.apply(TestActorRef.scala:144)
    at stashActorTest.StashTest$$anonfun$1.apply$mcV$sp(StashTestActor.scala:29)
    at stashActorTest.StashTest$$anonfun$1.apply(StashTestActor.scala:28)
    at stashActorTest.StashTest$$anonfun$1.apply(StashTestActor.scala:28)
    at org.scalatest.SuperEngine.registerNestedBranch(Engine.scala:613)
    at org.scalatest.WordSpecLike$class.org$scalatest$WordSpecLike$$registerBranch(WordSpecLike.scala:120)
    at org.scalatest.WordSpecLike$$anon$2.apply(WordSpecLike.scala:851)
    at org.scalatest.words.MustVerb$StringMustWrapperForVerb$class.must(MustVerb.scala:189)
    at org.scalatest.matchers.MustMatchers$StringMustWrapper.must(MustMatchers.scala:6167)
    at stashActorTest.StashTest.<init>(StashTestActor.scala:28)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at java.lang.Class.newInstance(Class.java:374)
    at org.scalatest.tools.Framework$ScalaTestTask.execute(Framework.scala:444)
    at sbt.TestRunner.runTest$1(TestFramework.scala:84)
    at sbt.TestRunner.run(TestFramework.scala:94)
    at sbt.TestFramework$$anon$2$$anonfun$$init$$1$$anonfun$apply$8.apply(TestFramework.scala:224)
    at sbt.TestFramework$$anon$2$$anonfun$$init$$1$$anonfun$apply$8.apply(TestFramework.scala:224)
    at sbt.TestFramework$.sbt$TestFramework$$withContextLoader(TestFramework.scala:212)
    at sbt.TestFramework$$anon$2$$anonfun$$init$$1.apply(TestFramework.scala:224)
    at sbt.TestFramework$$anon$2$$anonfun$$init$$1.apply(TestFramework.scala:224)
    at sbt.TestFunction.apply(TestFramework.scala:229)
    at sbt.Tests$$anonfun$7.apply(Tests.scala:196)
    at sbt.Tests$$anonfun$7.apply(Tests.scala:196)
    at sbt.std.Transform$$anon$3$$anonfun$apply$2.apply(System.scala:45)
    at sbt.std.Transform$$anon$3$$anonfun$apply$2.apply(System.scala:45)
    at sbt.std.Transform$$anon$4.work(System.scala:64)
    at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
    at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
    at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:18)
    at sbt.Execute.work(Execute.scala:244)
    at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
    at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
    at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:160)
    at sbt.CompletionService$$anon$2.call(CompletionService.scala:30)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
    at java.util.concurrent.FutureTask.run(FutureTask.java:166)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)
Caused by: akka.actor.ActorInitializationException: Could not instantiate Actor
Make sure Actor is NOT defined inside a class/trait,
if so put it outside the class/trait, f.e. in a companion object,
OR try to change: 'actorOf(Props[MyActor]' to 'actorOf(Props(new MyActor)'.
    at akka.actor.ActorInitializationException$.apply(Actor.scala:218)
    at akka.testkit.TestActorRef$$anonfun$apply$2$$anonfun$apply$1.applyOrElse(TestActorRef.scala:148)
    at akka.testkit.TestActorRef$$anonfun$apply$2$$anonfun$apply$1.applyOrElse(TestActorRef.scala:147)
    at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:33)
    at scala.util.Failure$$anonfun$recover$1.apply(Try.scala:185)
    at scala.util.Try$.apply(Try.scala:161)
    at scala.util.Failure.recover(Try.scala:185)
    at akka.testkit.TestActorRef$$anonfun$apply$2.apply(TestActorRef.scala:147)
    at akka.testkit.TestActorRef$$anonfun$apply$2.apply(TestActorRef.scala:153)
    at akka.actor.CreatorFunctionConsumer.produce(Props.scala:369)
    at akka.actor.Props.newActor(Props.scala:323)
    at akka.actor.ActorCell.newActor(ActorCell.scala:534)
    at akka.actor.ActorCell.create(ActorCell.scala:560)
    ... 58 more
Caused by: java.lang.NullPointerException
    at akka.actor.UnrestrictedStash$class.$init$(Stash.scala:82)
    at stashActorTest.StashTestActor.<init>(StashTestActor.scala:9)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$2.apply(DynamicAccess.scala:78)
    at scala.util.Try$.apply(Try.scala:161)
    at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:73)
    ... 64 more

我没有任何问题w将TestActorRefs与不会扩展Stash的actor一起使用。所以我不知道这是配置错误还是其他丢失的东西。

I don't have any problems with using TestActorRefs with actors that don't extend Stash. So I don't know if it is a configuration error or something else I'm missing.

推荐答案

TestActorRef不能与Stash一起使用。 TestActorRef需要CallingThreadMailbox,Stash需要DequeBasedMessageQueueSemantics。 文档应包含此限制,错误消息应得到改善

TestActorRef can't be used together with Stash. TestActorRef requires a CallingThreadMailbox and Stash requires DequeBasedMessageQueueSemantics. The documentation should include this limitation and the error messages should be improved.

这篇关于测试将Stash与TestActorRef混合的Akka演员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆