【问题标题】:My simple akka actor test is failing, what am I doing wrong?我简单的 akka 演员测试失败了,我做错了什么?
【发布时间】:2019-01-01 22:13:02
【问题描述】:

我正在尝试测试这个简单的演员:

object Notify {
  def props(incidentId: Int): Props = Props(new Notify(incidentId: Int))


  final case class Send(reportId: Int)
}

class Notify(incidentId: Int) extends Actor with ActorLogging {
  import Notify._

  log.info("Notify constructor...")

//  val x = 0
//  val y = 123 / x

  override def receive: Receive = {
    case Send(reportId) =>
      log.debug(s"Notify Send $reportId")
  }

}

我收到此错误:

  • should e f g * FAILED * [info] java.lang.AssertionError: assertion failed: timeout (3 seconds) during expectMsg while waiting 在 scala.Predef$.assert(Predef.scala:170) 处发送(123)[信息] [信息] 在 akka.testkit.TestKitBase$class.expectMsg_internal(TestKit.scala:402) [信息] 在 akka.testkit.TestKitBase$class.expectMsg(TestKit.scala:379) [信息]
    在 akka.testkit.TestKit.expectMsg(TestKit.scala:896) [信息] 在 TestKitUsageSpec$$anonfun$1$$anonfun$apply$mcV$sp$5.apply(ActorSpec.scala:49) [信息] 在 TestKitUsageSpec$$anonfun$1$$anonfun$apply$mcV$sp$5.apply(ActorSpec.scala:47) [信息] 在 org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85) [信息]
    在 org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104) [信息] 在 org.scalatest.Transformer.apply(Transformer.scala:22) [信息] 在 org.scalatest.Transformer.apply(Transformer.scala:20)

我的 akka 测试设置如下所示:

import scala.util.Random

import org.scalatest.BeforeAndAfterAll
import org.scalatest.WordSpecLike
import org.scalatest.Matchers

import com.typesafe.config.ConfigFactory

import akka.actor.Actor
import akka.actor.ActorRef
import akka.actor.ActorSystem
import akka.actor.Props
import akka.testkit.{ TestActors, DefaultTimeout, ImplicitSender, TestKit, TestProbe }
import scala.concurrent.duration._
import scala.collection.immutable

import com.example.notifications._

class TestKitUsageSpec
  extends TestKit(ActorSystem(
    "TestKitUsageSpec",
    ConfigFactory.parseString(TestKitUsageSpec.config)))
    with DefaultTimeout with ImplicitSender
    with WordSpecLike with Matchers with BeforeAndAfterAll {
  import TestKitUsageSpec._

  val echoRef = system.actorOf(TestActors.echoActorProps)
  val forwardRef = system.actorOf(Props(classOf[ForwardingActor], testActor))
  val filterRef = system.actorOf(Props(classOf[FilteringActor], testActor))
  val randomHead = Random.nextInt(6)
  val randomTail = Random.nextInt(10)
  val headList = immutable.Seq().padTo(randomHead, "0")
  val tailList = immutable.Seq().padTo(randomTail, "1")
  val seqRef =
    system.actorOf(Props(classOf[SequencingActor], testActor, headList, tailList))

  val notifyActor = system.actorOf(Notify.props(123))

  override def afterAll {
    shutdown()
  }

  "a b c d " should {
    "e f g" in {
      notifyActor ! Notify.Send(123)
      expectMsg(Notify.Send(123))
    }
  }

【问题讨论】:

  • 看起来您正在测试 Notify 将其 Send 消息回显给发件人 (expectMsg(Notify.Send(123))),但所有 Notify 参与者所做的只是记录其收到的 @987654327 @消息而什么都不做。因此,expectMsg 调用超时,因为没有发回任何内容,在此过程中产生异常。

标签: scala akka


【解决方案1】:

在您的测试中,您将向您的演员 (notifyActor ! Notify.Send(123)) 发送一条消息,然后您测试您的演员是否回复了相同的消息 (expectMsg(Notify.Send(123)))。

您的示例演员不响应请求。因此,您的测试有时会放弃等待响应超时异常。

要让您的测试运行,您必须让您的参与者响应请求。 您可以通过添加到接收方法来做到这一点:sender ! Notify.Send(123)

【讨论】:

  • 如果我的actor没有响应怎么办,我可以测试它是否收到了消息?
  • 测试Actor是否收到消息是对akka框架本身的测试,而不是你嵌入框架的逻辑。这不是 Akka 的 testkit 的重点。
  • @Blankman 如果你想测试它是否收到了一条消息,Notify 代理必须向它处理的消息的发件人发回某种形式的确认消息。然后您可以使用expectMsg 测试确认。例如,您可以有一个 Ack 案例类,其参数是收到的消息;将这样的实例作为消息发送回发件人将是证明您正确处理消息的一种方式。这可能不适合您的代码的生产版本。或者,查看Notify 的日志以获取消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-02
  • 1970-01-01
相关资源
最近更新 更多