akka: проверить сообщение по модулю некоторых полей
В настоящее время я тестирую приложение akka. Я столкнулся с определенной моделью: я хочу проверить, что TestProbe
получил определенное сообщение, по модулю некоторых полей.
Например, если сообщение было:
UserInfo(username: String, score: Int, timestamp: String)
Тогда я могу захотеть проверить username
а также score
как и ожидалось, но все равно, в какое время сообщение было получено.
В настоящее время я хотел бы написать что-то вроде этого:
testProbe.expectMsgPF() {
case UserInfo(`username`, `score`, _) =>
}
Как можно расширить класс тестового зонда, чтобы вместо этого можно было написать что-то подобное?
testProbe.expectApproxMsg(UserInfo(`username`, `score`, _))
Я надеюсь, что в дополнение к сокращению кода ответ на этот вопрос поможет мне лучше понять язык программирования Scala.
1 ответ
Я думаю, что вы не можете сделать что-то подобное
testProbe.expectApproxMsg(UserInfo(`username`, `score`, _))
Потому что первый последний атрибут (отметка времени) не является var
это val
должен иметь значение, и если вы хотите передать шаблон по параметру, вы тоже не можете, потому что мы не можем передать шаблон без всех case
альтернативы (PartialFunction).
Так UserInfo(
имя пользователя,
Гол, _)
это объект, нормальный экземпляр.
Но мы можем сделать обходной путь, расширяющий TestProbe
class и добавление значения по умолчанию к последнему классу атрибутов 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))
}
}