0
votes

I am trying to write a simple integration test for a scala application that uses the AKKA framework.

I want to

  1. have the application start on my local host
  2. write test cases that hit the application directly

I have done similar things things using springboottest but i can't seem to find anything remotely similar to this. I have been trying to read up on testkit routes and what not but it seems more like a unit test then it is a full application integration testing.

Any pointers or recommendations on what I am looking for would be great.

Thanks!

2

2 Answers

0
votes

First import

val akkaVersion = "2.6.10"

libraryDependencies ++= Seq(
  "com.typesafe.akka" %% "akka-actor" % akkaVersion,
  "com.typesafe.akka" %% "akka-testkit" % akkaVersion)

Create the actors

import akka.actor.{Actor, ActorSystem, Props}

object ActorsIntro extends App {

  run()

  def run() = {
    val actorSystem = ActorSystem("ActorsIntro")
    println(actorSystem.name)

    val worldCounter = actorSystem.actorOf(Props[WordCountActor], "WordCounter")
    val anotherWorldCounter = actorSystem.actorOf(Props[WordCountActor], "AnotherWordCounter")

    worldCounter ! "I am reviewing Akka using Scala and it is pretty damn awesome !"
    worldCounter ! "asynchronous message Akka Scala"
    anotherWorldCounter ! "asynchronous message Akka Scala"

    val person = actorSystem.actorOf(Person.props("Bob"))
    person ! "hi"
  }

  class WordCountActor extends Actor {
    var totalWords = 0

    override def receive: PartialFunction[Any, Unit] = {
      case message: String =>
        println(s"Message received[ $message ]")
        totalWords += message.split(" ").length
        println(s"Total words counted: $totalWords")
      case msg => println(s"word count. I cannot understand ${msg.toString}")
    }
  }

  object Person {
    def props(name: String) = Props(new Person(name))

    val propsPersonActor = {
      Props(new Person(""))
    }
  }

  class Person(name: String) extends Actor {
    override def receive: Receive = {
      case "hi" =>
        val reply = s"Hi, my name is $name"
        println(reply)
        sender() ! reply
      case message => sender() ! message
    }
  }

}

And its test case

import akka.actor.ActorSystem
import akka.testkit.{ImplicitSender, TestKit}
import org.scalatest.BeforeAndAfterAll
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike

class ActorsIntroTest extends TestKit(ActorSystem("ActorsIntroSpec"))
  with ImplicitSender
  with AnyWordSpecLike
  with Matchers
  with BeforeAndAfterAll {

  override def afterAll(): Unit = {
    TestKit.shutdownActorSystem(system)
  }

  "The ActorsIntro actor" should {
    "send back hi replay" in {
      val name = "Bob"
      val actorPerson = system.actorOf(ActorsIntro.Person.props(name))
      val hi = "hi"
      val hiReply = s"Hi, my name is $name"
      actorPerson ! hi
      expectMsg(hiReply)
    }

    "or send back the same message" in {
      val name = "Bob"
      val actorPerson = system.actorOf(ActorsIntro.Person.props(name))

      val message = "hello, test"
      actorPerson ! message
      expectMsg(message)
    }
  }
}
0
votes

If you want the application to run on localhost, I recommend you consider using akka http, so that you can bind a localhost server and test your app.