Как сделать тесты на реакцию актеров акка?

Я пытаюсь понять akka-Testkit "и надеюсь, что можно спросить об этом.

Я нашел несколько руководств и блогов, которые обращаются либо к атрибуту состояния, либо к атрибуту lastMsg- в нижележащем актере в TestActorRef. Однако TestActorRef из «akka-testkit_2.11»% «2.4.10» не имеет этих атрибутов. Я просмотрел пример на веб-сайте akka, и, возможно, мне что-то не хватает, но они показывают тестирование, среди прочего, эхо-актора, но не с помощью каких-либо простых реализаций акторов.

Итак, может ли кто-нибудь помочь мне понять, как протестировать воркера, который ответит тем же номером, если n% 3 == 0 (как в примере). Я бы предпочел не использовать future и шаблон запроса, если это возможно, и хотел бы протестировать ответ, который даст актер (с точки зрения этого актора, получив доступ к его состоянию или что-то подобное).

class ProjectEulerScalaTestAkka extends TestKit(ActorSystem("testing")) with WordSpecLike with MustMatchers {

    "A simple actor" must {
        val actorRef = TestActorRef[Worker]
        "receive messages" in {
             actorRef ! 3
             actorRef.underlyingActor.state//must not equal("world")
        }
    }
}

связанные: Как проверить актор Akka, который отправляет сообщение другому актеру?

На данный момент я использую подход синхронизированного тестирования;

 import akka.actor.ActorSystem
 import akka.testkit.{TestActorRef, TestKit}
 import org.scalatest.Matchers
 import org.scalatest.WordSpecLike
 import akka.pattern.ask
 import scala.concurrent.Future
 import scala.concurrent.duration._
 import scala.util.Success

class ProjectEulerScalaTestAkka extends TestKit(ActorSystem("testing")) with WordSpecLike with Matchers {
      implicit val time = akka.util.Timeout(100 seconds)
      "A simple actor" must {
           val actorRef = TestActorRef[Worker]
           "receive messages" in {
               val f = (actorRef ? 3).asInstanceOf[Future[Int]]
               val reply = f.value.get
               reply should equal (Success(3))
           }
      }
}

person stian    schedule 09.09.2016    source источник


Ответы (1)


Что я сделал, так это смоделировал интерфейс Актера, которому я отправлял сообщение, захватил сообщение и отправил обратно сообщение об успешном завершении в ссылку testActor.

объект успеха с полезной нагрузкой захваченного сообщения

case class SuccessWith(capturedMessage:Any = null)

фиктивный актер, которому вы отправляете свое сообщение, которое, в свою очередь, возвращает некоторое значение тестирующему актеру

case class MockActor(requester: ActorRef) extends Actor {
  override def receive: Receive = {
    case i: Int => {
      requester ! i
    }
  }
}

настроить актера, которого вы хотите для модульного тестирования

val actorRef = system.actorOf(Props(new YourActor(args)))

а затем ваш тест

  "A simple actor" must {
       "receive messages" in {
           val f = actorRef ! 3
           expectMsg(Success(3))
       }
  }
}
person nbpeth    schedule 13.03.2018
comment
Я тоже новичок в этом, но вы также можете взглянуть на TestProbe - вы можете передать ссылку на пробный актер и ожидать от него сообщений точно так же, как указано выше, но без конкретной реализации. - person nbpeth; 19.03.2018