1

我正在尝试A使用 Scaldi 在我的 Play 2.4 应用程序中测试一个 Actor。这个演员正在打电话injectActorRef[B],我想用TestKit.TestProbe.

在我的 specs2 中,我希望能够在B向 actor 提供相应的 TestKit.TestProbe.ref 的同时检索用于模拟的探针A

我想做这样的事情:

implicit val inj = (new TestModule(){
    bind[TestProbe] identifiedBy 'probeForB to TestProbe()
    bind[B] to inject[TestProbe]('probeForB).ref
}).injector

inject[TestProbe]('probeForB).expectMsgType[] must ...

问题是 ref 是一个,因此与预期的类型ActorRef不匹配。B

有没有一种干净的方法可以做到这一点?我们可以指定一个 ActorRef 返回injectActorRef[B]吗?


我最终覆盖了 Actor 的绑定A

val probeForB = TestProbe()

implicit val inj = (new Module() {
    bind[A] to new A() {
       override def injectB(): ActorRef = probeForB.ref
    }
 }).injector
4

1 回答 1

1

正如您所提到的,问题是inject[TestProbe]('probeForB).ref给您一个ActorRef支持而不是实际演员的实例。

如果您想以您描述的方式对其进行测试,那么您还需要定义一个ActorReffor actor的绑定B。例如:

bind [BActor] toProvider new BActor
bind [ActorRef] identifiedBy 'bRef to {
  implicit val system = inject [ActorSystem]
  injectActorRef[BActor]
}

完成此设置后,您可以使用测试探针覆盖第二个绑定:

bind [ActorRef] identifiedBy 'bRef to inject[TestProbe]('probeForB).ref

请注意,这个例子不是直接等效的,因为BActor现在有一个不同的主管(监护人演员,这就是我们需要在ActorSystem这里注入的原因)。

injectActorRef使用 .将 Actor 创建委托给“上下文”(父 Actor 或 Actor 系统)context.actorOf。它的有用之处在于它创建了一个特殊的,当 akka 想要创建一个类时Props注入新的类实例。BActor这意味着 scaldi 无法控制 actor 的生命周期(这非常重要,因为 akka 本身对此具有非常复杂的机制),它只是为 akka 提供了如何创建特定 actor 类的新实例的知识。

如果你在另一个actor中创建一个actor(就像你描述的那样),那么它们的生命周期都是由akka紧密连接和管理的。这就是为什么在这种情况下您不能简单地覆盖和Actor绑定ActorRef测试绑定的原因。

于 2015-10-21T16:45:30.350 回答