When testing Akka actor I receive the error: no matching constructor found on MyActor
When testing Akka actor I receive the error: no matching constructor found on MyActor
我正在为 Akka 演员创建测试,但出于某种原因,它不允许我创建演员。它会抛出一条消息说 no matching constructor found on class SimpleActor
。这似乎是 Akka 版本 2.4.x 基于 on this issue 的错误,但我使用的是较新的版本。我正在使用以下 build.sbt
:
name := """explore-akka"""
version := "1.1"
scalaVersion := "2.12.7"
val akkaVersion = "2.6.10"
val scalaBinVersion = "2.12"
val scalaTestVersion = "3.2.2"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % akkaVersion,
"com.typesafe.akka" %% "akka-testkit" % akkaVersion,
"org.scalatest" %% "scalatest" % scalaTestVersion
)
mainClass in Compile := Some("org.github.felipegutierrez.explore.akka.MainClass")
enablePlugins(JavaAppPackaging)
enablePlugins(DockerPlugin)
dockerUsername := Some("felipeogutierrez")
以及 Scala 中的以下测试 class:
package org.github.felipegutierrez.explore.akka.tests
import akka.actor.{Actor, ActorSystem, Props}
import akka.testkit.{ImplicitSender, TestKit}
import org.scalatest.BeforeAndAfterAll
import org.scalatest.wordspec.AnyWordSpecLike
class BasicSpec extends TestKit(ActorSystem())
with ImplicitSender with AnyWordSpecLike with BeforeAndAfterAll {
override def afterAll(): Unit = {
TestKit.shutdownActorSystem(system)
}
import BasicSpec._
"a simple actor" should {
"send back the same message" in {
val echoActor = system.actorOf(Props[SimpleActor])
val message = "hello, test"
echoActor ! message
expectMsg(message)
}
}
object BasicSpec {
class SimpleActor extends Actor {
override def receive: Receive = {
case message => sender() ! message
}
}
}
}
我也试过 val echoActor = system.actorOf(Props[SimpleActor], name = "SimpleActor")
和 val echoActor = TestActorRef(Props[SimpleActor])
但我一直收到这个错误:
no matching constructor found on class org.github.felipegutierrez.explore.akka.tests.BasicSpec$BasicSpec$SimpleActor for arguments []
java.lang.IllegalArgumentException: no matching constructor found on class org.github.felipegutierrez.explore.akka.tests.BasicSpec$BasicSpec$SimpleActor for arguments []
at akka.util.Reflect$.error(Reflect.scala:89)
at akka.util.Reflect$.findConstructor(Reflect.scala:113)
at akka.actor.NoArgsReflectConstructor.<init>(IndirectActorProducer.scala:108)
at akka.actor.IndirectActorProducer$.apply(IndirectActorProducer.scala:63)
at akka.actor.Props.producer(Props.scala:131)
at akka.actor.Props.<init>(Props.scala:144)
at akka.actor.Props$.apply(Props.scala:62)
at org.github.felipegutierrez.explore.akka.tests.BasicSpec.$anonfun$new(BasicSpec.scala:20)
at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
at org.scalatest.Transformer.apply(Transformer.scala:22)
at org.scalatest.Transformer.apply(Transformer.scala:20)
at org.scalatest.wordspec.AnyWordSpecLike$$anon.apply(AnyWordSpecLike.scala:1076)
at org.scalatest.TestSuite.withFixture(TestSuite.scala:196)
at org.scalatest.TestSuite.withFixture$(TestSuite.scala:195)
at org.github.felipegutierrez.explore.akka.tests.BasicSpec.withFixture(BasicSpec.scala:8)
at org.scalatest.wordspec.AnyWordSpecLike.invokeWithFixture(AnyWordSpecLike.scala:1074)
at org.scalatest.wordspec.AnyWordSpecLike.$anonfun$runTest(AnyWordSpecLike.scala:1086)
at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306)
at org.scalatest.wordspec.AnyWordSpecLike.runTest(AnyWordSpecLike.scala:1086)
at org.scalatest.wordspec.AnyWordSpecLike.runTest$(AnyWordSpecLike.scala:1068)
at org.github.felipegutierrez.explore.akka.tests.BasicSpec.runTest(BasicSpec.scala:8)
at org.scalatest.wordspec.AnyWordSpecLike.$anonfun$runTests(AnyWordSpecLike.scala:1145)
at org.scalatest.SuperEngine.$anonfun$runTestsInBranch(Engine.scala:413)
at scala.collection.immutable.List.foreach(List.scala:388)
at org.scalatest.SuperEngine.traverseSubNodes(Engine.scala:401)
at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:390)
at org.scalatest.SuperEngine.$anonfun$runTestsInBranch(Engine.scala:427)
at scala.collection.immutable.List.foreach(List.scala:388)
at org.scalatest.SuperEngine.traverseSubNodes(Engine.scala:401)
at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:396)
at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:475)
at org.scalatest.wordspec.AnyWordSpecLike.runTests(AnyWordSpecLike.scala:1145)
at org.scalatest.wordspec.AnyWordSpecLike.runTests$(AnyWordSpecLike.scala:1144)
at org.github.felipegutierrez.explore.akka.tests.BasicSpec.runTests(BasicSpec.scala:8)
at org.scalatest.Suite.run(Suite.scala:1112)
at org.scalatest.Suite.run$(Suite.scala:1094)
at org.github.felipegutierrez.explore.akka.tests.BasicSpec.org$scalatest$wordspec$AnyWordSpecLike$$super$run(BasicSpec.scala:8)
at org.scalatest.wordspec.AnyWordSpecLike.$anonfun$run(AnyWordSpecLike.scala:1190)
at org.scalatest.SuperEngine.runImpl(Engine.scala:535)
at org.scalatest.wordspec.AnyWordSpecLike.run(AnyWordSpecLike.scala:1190)
at org.scalatest.wordspec.AnyWordSpecLike.run$(AnyWordSpecLike.scala:1188)
at org.github.felipegutierrez.explore.akka.tests.BasicSpec.org$scalatest$BeforeAndAfterAll$$super$run(BasicSpec.scala:8)
at org.scalatest.BeforeAndAfterAll.liftedTree1(BeforeAndAfterAll.scala:213)
at org.scalatest.BeforeAndAfterAll.run(BeforeAndAfterAll.scala:210)
at org.scalatest.BeforeAndAfterAll.run$(BeforeAndAfterAll.scala:208)
at org.github.felipegutierrez.explore.akka.tests.BasicSpec.run(BasicSpec.scala:8)
at org.scalatest.tools.SuiteRunner.run(SuiteRunner.scala:45)
at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun(Runner.scala:1320)
at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$adapted(Runner.scala:1314)
at scala.collection.immutable.List.foreach(List.scala:388)
at org.scalatest.tools.Runner$.doRunRunRunDaDoRunRun(Runner.scala:1314)
at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter(Runner.scala:993)
at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$adapted(Runner.scala:971)
at org.scalatest.tools.Runner$.withClassLoaderAndDispatchReporter(Runner.scala:1480)
at org.scalatest.tools.Runner$.runOptionallyWithPassFailReporter(Runner.scala:971)
at org.scalatest.tools.Runner$.run(Runner.scala:798)
at org.scalatest.tools.Runner.run(Runner.scala)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.runScalaTest2or3(ScalaTestRunner.java:40)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.main(ScalaTestRunner.java:27)
更新: 更奇怪的是,当我使用 the official doc 中的以下测试时,它有效!但是,当我将相同的代码从 TestActors.echoActorProps
复制到我的 SimpleActor 时,它不起作用。
"An Echo actor" must {
"send back messages unchanged" in {
val echo = system.actorOf(TestActors.echoActorProps)
echo ! "hello world"
expectMsg("hello world")
}
}
我更改了 val propsSimpleActor = {Props(new SimpleActor)}
的实现并且它起作用了。我不确定为什么即使我从 official documentation 实现了相同的代码也无法正常工作。完整代码如下:
package org.github.felipegutierrez.explore.akka.tests
import akka.actor.{Actor, ActorSystem, Props}
import akka.testkit.{ImplicitSender, TestActors, TestKit}
import org.scalatest.BeforeAndAfterAll
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike
import scala.concurrent.duration.DurationInt
import scala.util.Random
class BasicSpec extends TestKit(ActorSystem("BasicSpec"))
with ImplicitSender
with AnyWordSpecLike
with Matchers
with BeforeAndAfterAll {
override def afterAll(): Unit = { TestKit.shutdownActorSystem(system) }
"A simple actor" should {
"send back the same message" in {
val echoActor = system.actorOf(BasicSpec.propsSimpleActor)
val message = "hello, test"
echoActor ! message
expectMsg(message)
}
}
object BasicSpec {
class SimpleActor extends Actor {
override def receive = {
case message => sender() ! message
}
}
val propsSimpleActor = {Props(new SimpleActor)}
}
}
我正在为 Akka 演员创建测试,但出于某种原因,它不允许我创建演员。它会抛出一条消息说 no matching constructor found on class SimpleActor
。这似乎是 Akka 版本 2.4.x 基于 on this issue 的错误,但我使用的是较新的版本。我正在使用以下 build.sbt
:
name := """explore-akka"""
version := "1.1"
scalaVersion := "2.12.7"
val akkaVersion = "2.6.10"
val scalaBinVersion = "2.12"
val scalaTestVersion = "3.2.2"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % akkaVersion,
"com.typesafe.akka" %% "akka-testkit" % akkaVersion,
"org.scalatest" %% "scalatest" % scalaTestVersion
)
mainClass in Compile := Some("org.github.felipegutierrez.explore.akka.MainClass")
enablePlugins(JavaAppPackaging)
enablePlugins(DockerPlugin)
dockerUsername := Some("felipeogutierrez")
以及 Scala 中的以下测试 class:
package org.github.felipegutierrez.explore.akka.tests
import akka.actor.{Actor, ActorSystem, Props}
import akka.testkit.{ImplicitSender, TestKit}
import org.scalatest.BeforeAndAfterAll
import org.scalatest.wordspec.AnyWordSpecLike
class BasicSpec extends TestKit(ActorSystem())
with ImplicitSender with AnyWordSpecLike with BeforeAndAfterAll {
override def afterAll(): Unit = {
TestKit.shutdownActorSystem(system)
}
import BasicSpec._
"a simple actor" should {
"send back the same message" in {
val echoActor = system.actorOf(Props[SimpleActor])
val message = "hello, test"
echoActor ! message
expectMsg(message)
}
}
object BasicSpec {
class SimpleActor extends Actor {
override def receive: Receive = {
case message => sender() ! message
}
}
}
}
我也试过 val echoActor = system.actorOf(Props[SimpleActor], name = "SimpleActor")
和 val echoActor = TestActorRef(Props[SimpleActor])
但我一直收到这个错误:
no matching constructor found on class org.github.felipegutierrez.explore.akka.tests.BasicSpec$BasicSpec$SimpleActor for arguments []
java.lang.IllegalArgumentException: no matching constructor found on class org.github.felipegutierrez.explore.akka.tests.BasicSpec$BasicSpec$SimpleActor for arguments []
at akka.util.Reflect$.error(Reflect.scala:89)
at akka.util.Reflect$.findConstructor(Reflect.scala:113)
at akka.actor.NoArgsReflectConstructor.<init>(IndirectActorProducer.scala:108)
at akka.actor.IndirectActorProducer$.apply(IndirectActorProducer.scala:63)
at akka.actor.Props.producer(Props.scala:131)
at akka.actor.Props.<init>(Props.scala:144)
at akka.actor.Props$.apply(Props.scala:62)
at org.github.felipegutierrez.explore.akka.tests.BasicSpec.$anonfun$new(BasicSpec.scala:20)
at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
at org.scalatest.Transformer.apply(Transformer.scala:22)
at org.scalatest.Transformer.apply(Transformer.scala:20)
at org.scalatest.wordspec.AnyWordSpecLike$$anon.apply(AnyWordSpecLike.scala:1076)
at org.scalatest.TestSuite.withFixture(TestSuite.scala:196)
at org.scalatest.TestSuite.withFixture$(TestSuite.scala:195)
at org.github.felipegutierrez.explore.akka.tests.BasicSpec.withFixture(BasicSpec.scala:8)
at org.scalatest.wordspec.AnyWordSpecLike.invokeWithFixture(AnyWordSpecLike.scala:1074)
at org.scalatest.wordspec.AnyWordSpecLike.$anonfun$runTest(AnyWordSpecLike.scala:1086)
at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306)
at org.scalatest.wordspec.AnyWordSpecLike.runTest(AnyWordSpecLike.scala:1086)
at org.scalatest.wordspec.AnyWordSpecLike.runTest$(AnyWordSpecLike.scala:1068)
at org.github.felipegutierrez.explore.akka.tests.BasicSpec.runTest(BasicSpec.scala:8)
at org.scalatest.wordspec.AnyWordSpecLike.$anonfun$runTests(AnyWordSpecLike.scala:1145)
at org.scalatest.SuperEngine.$anonfun$runTestsInBranch(Engine.scala:413)
at scala.collection.immutable.List.foreach(List.scala:388)
at org.scalatest.SuperEngine.traverseSubNodes(Engine.scala:401)
at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:390)
at org.scalatest.SuperEngine.$anonfun$runTestsInBranch(Engine.scala:427)
at scala.collection.immutable.List.foreach(List.scala:388)
at org.scalatest.SuperEngine.traverseSubNodes(Engine.scala:401)
at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:396)
at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:475)
at org.scalatest.wordspec.AnyWordSpecLike.runTests(AnyWordSpecLike.scala:1145)
at org.scalatest.wordspec.AnyWordSpecLike.runTests$(AnyWordSpecLike.scala:1144)
at org.github.felipegutierrez.explore.akka.tests.BasicSpec.runTests(BasicSpec.scala:8)
at org.scalatest.Suite.run(Suite.scala:1112)
at org.scalatest.Suite.run$(Suite.scala:1094)
at org.github.felipegutierrez.explore.akka.tests.BasicSpec.org$scalatest$wordspec$AnyWordSpecLike$$super$run(BasicSpec.scala:8)
at org.scalatest.wordspec.AnyWordSpecLike.$anonfun$run(AnyWordSpecLike.scala:1190)
at org.scalatest.SuperEngine.runImpl(Engine.scala:535)
at org.scalatest.wordspec.AnyWordSpecLike.run(AnyWordSpecLike.scala:1190)
at org.scalatest.wordspec.AnyWordSpecLike.run$(AnyWordSpecLike.scala:1188)
at org.github.felipegutierrez.explore.akka.tests.BasicSpec.org$scalatest$BeforeAndAfterAll$$super$run(BasicSpec.scala:8)
at org.scalatest.BeforeAndAfterAll.liftedTree1(BeforeAndAfterAll.scala:213)
at org.scalatest.BeforeAndAfterAll.run(BeforeAndAfterAll.scala:210)
at org.scalatest.BeforeAndAfterAll.run$(BeforeAndAfterAll.scala:208)
at org.github.felipegutierrez.explore.akka.tests.BasicSpec.run(BasicSpec.scala:8)
at org.scalatest.tools.SuiteRunner.run(SuiteRunner.scala:45)
at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun(Runner.scala:1320)
at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$adapted(Runner.scala:1314)
at scala.collection.immutable.List.foreach(List.scala:388)
at org.scalatest.tools.Runner$.doRunRunRunDaDoRunRun(Runner.scala:1314)
at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter(Runner.scala:993)
at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$adapted(Runner.scala:971)
at org.scalatest.tools.Runner$.withClassLoaderAndDispatchReporter(Runner.scala:1480)
at org.scalatest.tools.Runner$.runOptionallyWithPassFailReporter(Runner.scala:971)
at org.scalatest.tools.Runner$.run(Runner.scala:798)
at org.scalatest.tools.Runner.run(Runner.scala)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.runScalaTest2or3(ScalaTestRunner.java:40)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.main(ScalaTestRunner.java:27)
更新: 更奇怪的是,当我使用 the official doc 中的以下测试时,它有效!但是,当我将相同的代码从 TestActors.echoActorProps
复制到我的 SimpleActor 时,它不起作用。
"An Echo actor" must {
"send back messages unchanged" in {
val echo = system.actorOf(TestActors.echoActorProps)
echo ! "hello world"
expectMsg("hello world")
}
}
我更改了 val propsSimpleActor = {Props(new SimpleActor)}
的实现并且它起作用了。我不确定为什么即使我从 official documentation 实现了相同的代码也无法正常工作。完整代码如下:
package org.github.felipegutierrez.explore.akka.tests
import akka.actor.{Actor, ActorSystem, Props}
import akka.testkit.{ImplicitSender, TestActors, TestKit}
import org.scalatest.BeforeAndAfterAll
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike
import scala.concurrent.duration.DurationInt
import scala.util.Random
class BasicSpec extends TestKit(ActorSystem("BasicSpec"))
with ImplicitSender
with AnyWordSpecLike
with Matchers
with BeforeAndAfterAll {
override def afterAll(): Unit = { TestKit.shutdownActorSystem(system) }
"A simple actor" should {
"send back the same message" in {
val echoActor = system.actorOf(BasicSpec.propsSimpleActor)
val message = "hello, test"
echoActor ! message
expectMsg(message)
}
}
object BasicSpec {
class SimpleActor extends Actor {
override def receive = {
case message => sender() ! message
}
}
val propsSimpleActor = {Props(new SimpleActor)}
}
}