【问题标题】:Akka actors unit testing with Scala使用 Scala 进行 Akka Actor 单元测试
【发布时间】:2013-05-23 02:14:12
【问题描述】:

我对 Scala 还很陌生,所以请保持温和。

在我目前正在构建的应用程序中,我正在使用 Akka 演员,我想编写一些单元测试。我遇到了这个official documentation for writing unit tests for Akka actors

但我无法准确理解它应该如何工作。特别是,

val actorRef = TestActorRef(new MyActor)
// hypothetical message stimulating a '42' answer
val future = actorRef ? Say42
val Success(result: Int) = future.value.get
result must be(42)

当我尝试这样做时,我得到了not found: value Success,这并不奇怪。

然后我找到了this example of how to test Scala actors

val actorRef = TestActorRef[TickTock]

implicit val timeout = Timeout(5 seconds)
val future = (actorRef ? new Tick("msg")).mapTo[String]
val result = Await.result(future, timeout.duration)

Assert.assertEquals("processed the tick message", result)

,诚然,它可能已经过时了,但它很容易理解,并且更接近我想使用 Futures 时通常使用的东西,而且最重要的是有效。它确实需要我声明一些隐式,例如 ActorSystem、超时等,而官方的方式似乎并非如此......

如果可能的话,我想使用官方文档提出的方法,所以如果有人能帮助我理解它是如何工作的(特别是 Success 位)以及如何使用它,我将不胜感激。

【问题讨论】:

  • 你有像 scala.util._scala.util.Success 这样的导入吗?

标签: scala testing akka actor specs


【解决方案1】:

让您的测试扩展 TestKit,然后添加“with ImplicitSender”,然后您可以执行以下操作:

val yourActor = system.actorOf(Props[MyActor])
yourActor ! Say42
expectMsg(42)

【讨论】:

  • 谢谢,这真的很有帮助。经过一番搜索,我发现 this example 演示了如何使用 ImplicitSender 和 DefaultTimeout 等。
【解决方案2】:

首先,在期货价值上使用 get 不是一个好的模式,如果失败,这可能会引发异常。您应该使用 Await.result,就像在您的第二个示例中一样,或者使用模式匹配来处理成功和失败:

future match {
  case Success(value) => // work with value
  case Failure(ex) => // work with exception
}

使用SuccessFailure 导入scala.util._scala.util.{Success, Failure}

Here 是最新版本 2.2-M3 的官方文档。

【讨论】:

    【解决方案3】:

    您的问题的答案可能太长,因为不可能知道您实际了解多少 Scala。我会尽量缩短我的回答,但不要犹豫随时要求澄清。我也代表整个 stackoverflow 社区向您道歉,因为在提问之前明显缺乏技巧,让您感到有必要道歉。

    在 Scala 2.10 中引入了Try 的概念。它与Option 非常相似。 Option 是处理nulls 的概念。 Option 类型的值可以采用两种形式:Some(value)None。当您有 Optional 值时,您可以对其进行模式匹配以查看它是 Some 还是 None,然后采取相应措施。模式匹配发生在 Scala 的许多地方,其中之一是在 vals 的初始化期间。以下是几个例子:

    val x = 10 // pattern 'x' on the LHS matches any value on the RHS so 'x' is initialized with 10
    val Some(x) = Some(10) // pattern 'Some(x)' on the LHS matches any value of type 'Some' and binds it's value to x, so 'x' is yet again initialized with 10
    

    Try是处理异常的概念。 Try 类型的值可以采用两种形式:Success(result)Failure(throwable)。当您有一个 Try 类型的值时,您可以对其进行模式匹配以查看它是 Success 还是 Failure

    这就是您的代码中发生的情况(Success 上的模式匹配)。与Option相反,Try这两种形式默认不在作用域内,导致编译错误。这将解决它:

    import scala.util.{Try, Success, Failure}
    

    【讨论】:

    • 很好的比喻;我非常了解模式匹配和选项,并且能够跟进。我只是不知道尝试、成功和失败。我想那 Future.value.get 那么返回一个 Try 类型的值呢?换句话说,以下方式的示例:val futureValue= future.value.get futureValue match { case Success(x:Int) => x must be(42) case _ => false must be(true) //just fail } 以上在我的测试中对我有用:)
    • 是的,完全一样,但您绝对应该采用 Viktor Klang 建议的方法。
    • 谢谢,我会接受你的回答,因为它回答了我的问题,最能消除我对成功的困惑。
    猜你喜欢
    • 2015-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 2018-03-10
    • 1970-01-01
    • 2019-02-12
    • 2012-05-20
    相关资源
    最近更新 更多