我目前正在测试akka应用程序。
我遇到了某种模式:我想测试一个TestProbe
收到某个消息,模拟一些字段。
例如,如果消息是:
UserInfo(username: String, score: Int, timestamp: String)
然后我可能希望测试username
和score
是否符合预期,但不关心收到邮件的时间。
目前我想写这样的东西:
testProbe.expectMsgPF() {
case UserInfo(`username`, `score`, _) =>
}
如何扩展测试探针类,以便可以编写类似的东西?
testProbe.expectApproxMsg(UserInfo(`username`, `score`, _))
除了缩短我的代码之外,我希望这个问题的答案能够进一步理解我对Scala编程语言的理解。
答案 0 :(得分:0)
我认为你不能做这样的事情
testProbe.expectApproxMsg(UserInfo(`username`, `score`, _))
因为,第一个属性(时间戳)不是var
,val
需要有值,如果你想要的是通过参数传递一个模式,你不能“导致我们没有所有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))
}
}