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))

  }
}

Исходный код Testkit

Другие вопросы по тегам