【问题标题】:Spock mocks for Akka's ActorRefSpock 嘲笑 Akka 的 ActorRef
【发布时间】:2012-06-03 08:41:12
【问题描述】:

我尝试为一个类进行 Spock 测试,我需要检查它是否向参与者发送了一条消息(比如statActor)。我知道 Akka 有专门的集成测试库,但对于非常简单的测试来说似乎太多了。所以,我试过了:

setup:
def myActor = Mock(ActorRef)
myService.statActor = myActor
when:
myService.startStats()
then:
1 * myActor.tell(_)

目标方法如下:

void startStats() {
    Date x = null
    // prepare some data, fill x with required value
    this.statActor.tell(x)
}

我以为 Spock 会使用 tell 方法创建模拟。但运行此测试后,我得到:

java.lang.ClassCastException: akka.actor.ActorRef$$EnhancerByCGLIB$$80b97938 cannot be cast to akka.actor.ScalaActorRef
    at akka.actor.ActorRef.tell(ActorRef.scala:95)
    at com.example.MyService.startStats(MyService.groovy:32)

为什么它调用真正的ActorRef 实现?某种与 Scala 的不兼容?有什么方法可以模拟这样的课程吗?

【问题讨论】:

  • "但是对于非常简单的测试来说似乎太多了"
  • @ViktorKlang 因为一行def actor = Mock(ActorRef) 少于testkit 所需的几十行。我的意思是它可以模拟其他对象,工作正常且非常易于使用
  • @paradigmatic 是的,我知道。可能我在问尖锐的问题,但我能在这里做什么? :(

标签: scala groovy akka spock


【解决方案1】:

唯一受支持的模拟 ActorRef 的方法是创建一个 TestProbe:

// "system" is an ActorSystem
final TestProbe probe = TestProbe.apply(system);
final ActorRef mock = probe.ref;

没有比这更容易或更简单的了。

【讨论】:

  • 谢谢。我如何测试 .tell() 是否为这个演员调用了一个我也可以测试的值?
  • 有很多方法可以在探针上断言消息接收,列在doc.akka.io/api/akka/2.0/akka/testkit/TestProbe.html
  • 哦,我确定和TestActorRef是一样的
  • @Roland Kuhn 实际上我已经询问过如何将它与 Spock 一起使用。据我了解,您的意思是没有办法为 Akka 使用标准的 Spock 模拟,对吧?
  • @Igor:如果您想为 Akka 编写自己的测试套件,请随意。
【解决方案2】:

在 specs2 中你可以这样做:

val mockedActorRef = spy(TestProbe().ref)

然后照常使用。

【讨论】:

    猜你喜欢
    • 2020-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    • 2021-08-03
    • 2016-10-02
    • 2019-12-20
    • 1970-01-01
    相关资源
    最近更新 更多