akka:测试以某些字段为模的消息

时间:2015-12-28 19:56:23

标签: scala unit-testing akka akka-testkit testkit

我目前正在测试akka应用程序。 我遇到了某种模式:我想测试一个TestProbe收到某个消息,模拟一些字段。

例如,如果消息是:

UserInfo(username: String, score: Int, timestamp: String)

然后我可能希望测试usernamescore是否符合预期,但不关心收到邮件的时间。

目前我想写这样的东西:

testProbe.expectMsgPF() {
  case UserInfo(`username`, `score`, _) =>
}

如何扩展测试探针类,以便可以编写类似的东西?

testProbe.expectApproxMsg(UserInfo(`username`, `score`, _))

除了缩短我的代码之外,我希望这个问题的答案能够进一步理解我对Scala编程语言的理解。

1 个答案:

答案 0 :(得分:0)

我认为你不能做这样的事情

testProbe.expectApproxMsg(UserInfo(`username`, `score`, _))

因为,第一个属性(时间戳)不是varval需要有值,如果你想要的是通过参数传递一个模式,你不能“导致我们没有所有case替代品(PartialFunction),不能单独传递模式。

所以UserInfo(用户名,得分, _)是一个对象,一个普通的实例。

但我们可以做一个解决方法,扩展TestProbe类并为上一个UserInfo的属性类添加一个默认值。

请看以下内容,也许它适合您:

HelloSpec.scala

import org.scalatest._
import scala.concurrent.duration._
import akka.testkit._
import akka.testkit._
import akka.actor._


case class UserInfo(username: String, score: Int, timestamp: String = "")

case class MyTestProbe(_application: ActorSystem) extends TestProbe(_application) {
        def expectApproxMsg(max: Duration = Duration.Undefined, us:UserInfo):UserInfo = {
                val obj = receiveOne(max).asInstanceOf[UserInfo]
                assert(obj ne null, s"timeout ($max) during expectMsg while waiting for $us")
                val expect = us.username == obj.username && us.score == obj.score
                assert(expect, s"expected $us, found $obj")
                obj
        }
}

class HelloSpec extends FlatSpec with Matchers with TestKitBase {
 implicit lazy val system = ActorSystem()
  "TestProbe actor" should "receive correct message" in {

        val probe2 = MyTestProbe(system)
        probe2.ref ! UserInfo("Salc2",9999,"whatever")
        probe2.expectApproxMsg(500 millis, UserInfo("Salc2",9999))

  }
}

Source code of Testkit