首页 > 解决方案 > 如何从类型参数实例化 Akka 演员

问题描述

我正在为 Akka 应用程序搭建测试脚手架,我希望将参与者注入测试类:

import akka.actor.ActorSystem
import akka.testkit.{ ImplicitSender, TestActors, TestKit }
import org.scalatest.{ BeforeAndAfterAll, Matchers, WordSpecLike }
import akka.actor.Props
import akka.actor.Actor
import akka.event.Logging
import akka.actor.ActorRef

class Simulation[A <: SimulationActor : scala.reflect.ClassTag]
  extends TestKit(ActorSystem("AkkaSimulation")) with ImplicitSender
    with WordSpecLike with Matchers with BeforeAndAfterAll {

    override def afterAll {
      TestKit.shutdownActorSystem(system)
    }

   val invariantActor1 = system.actorOf(Props(classOf[A1]))
   val invariantActor2 = system.actorOf(Props(classOf[A2], invariantActor1))
   val actorUnderTest = system.actorOf(Props[SimulationActor]) // how to pass additional argument to Props here?


  // test logic here

}

// then elsewhere use the above template:
class Simulation1 extends Simulation[Sim1]
class Simulation2 extends Simulation[Sim2]
class Simulation extends Simulation[Sim3]
// and so on...

我在此设计中遇到以下良性问题:

在提供类型参数 A 时,我在向 传递附加值参数时迷失了方向Props。找不到适用于这种情况的语法,开始怀疑是否Props以任何简单的方式启用此用例。以下行需要传递一个ActorRef参数,因为SimulationActor需要一个参数,但我找不到通过它的方法。是否有另一种参与者实例化形式,它允许参与者类型的类型参数和参与者构造函数的值参数?

val actorUnderTest = system.actorOf(Props[SimulationActor])

似乎不支持:

val actorUnderTest = system.actorOf(Props[SimulationActor], invariantActor2)

在这个阶段我对介绍 Akka Typed 保持沉默。为了纯粹的优雅,最好不要在启动后更改目标actor以将其值参数作为消息接收,否则这是一种临时的解决方法。

标签: scalaakka

解决方案


似乎Props没有足够的构造函数用于此,所以ClassTag来救援!

import scala.reflect.ClassTag

class Simulation[A <: WorldSimulationActor : scala.reflect.ClassTag](implicit tag: ClassTag[A])

    .
    .
    .

  val actorUnderTestr = system.actorOf(Props(tag.runtimeClass, invariantActor2))

瞧。如果API 文档中隐藏了一些更简单的东西,我肯定没有发现它。


推荐阅读