wefree 2023. 7. 18. 16:30
libraryDependencies += "com.typesafe.akka" %% "akka-actor-typed" % "2.6.18"
libraryDependencies += "com.typesafe.akka" %% "akka-actor-testkit-typed" % "2.6.18"
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.9"
import AkkaBasicSpec._

import akka.actor.{Actor, ActorSystem, Props}
import akka.testkit.{ImplicitSender, TestKit}
import org.scalatest.BeforeAndAfterAll
import org.scalatest.wordspec.AnyWordSpecLike

import java.util.Random
import scala.concurrent.duration._

class AkkaBasicSpec
    extends TestKit(ActorSystem("BasicSpec"))
    with ImplicitSender
    with AnyWordSpecLike
    with BeforeAndAfterAll {
    
  override def afterAll(): Unit = {
    TestKit.shutdownActorSystem(system)
  }

  "A simple actor" should {
    "send back the same message" in {
      val echoActor = system.actorOf(Props[SimpleActor], "simpleActor")
      val message = "Hello Test"

      echoActor ! message
      expectMsg(message)
    }
  }

  "A Blackhole actor" should {
    "send back some message" in {
      val blackholeActor = system.actorOf(Props[BlackholeActor], "blackholeActor")
      val message = "Hello Test"

      blackholeActor ! message
      expectNoMessage(1.second)
    }
  }

  "A Lab Test actor" should {
    val labTestActor = system.actorOf(Props[LabTestActor], "labTestActor")

    "turn a string into uppercase" in {
      labTestActor ! "I love akka"

      // expectMsg("I LOVE AKKA")
      val reply = expectMsgType[String]
      assert(reply == "I LOVE AKKA")
    }

    "reply to greeting" in {
      labTestActor ! "greeting"
      expectMsgAnyOf("hi", "hello")
    }

    "reply to favoriteTech" in {
      labTestActor ! "favoriteTech"
      expectMsgAllOf("scala", "akka")
    }

    "reply to favoriteTech in a different way" in {
      labTestActor ! "favoriteTech"

      val messages: Seq[Any] = receiveN(2)
      assert(messages(0) == "scala")
      assert(messages(1) == "akka")
    }

  }
}

object AkkaBasicSpec {
  class SimpleActor extends Actor {
    override def receive: Receive = { case message =>
      println(message.toString)
      sender() ! message
    }
  }

  class BlackholeActor extends Actor {
    override def receive: Receive = { case message =>
      Actor.emptyBehavior
    }
  }

  class LabTestActor extends Actor {
    val random = new Random()
    override def receive: Receive = {
      case "greeting" =>
        if (random.nextBoolean()) {
          sender() ! "hi"
        } else {
          sender() ! "hello"
        }

      case "favoriteTech" =>
        sender() ! "scala"
        sender() ! "akka"

      case message: String => sender() ! message.toUpperCase
    }
  }
}