0

I have started writing test for scala actor. I read this blog. http://blog.matthieuguillermin.fr/2013/06/akka-testing-your-actors/ Then I started. I wrote Application Actor. But I realized the application actor which is different others are in blog. Because the actor is as main class. It wrote string on console and sended message another actor. How can I test application actor?

    class Application extends Actor{

      val cliCommandExecute = context.actorOf(Props[CLICommandExecute],"CLICommandExecute")
      println(Util.welcomeMessage)
      cliCommandExecute ! CLICommandExecute.Listen(self)

      def receive = {
        case CLICommandExecute.Done(result: String) => {
          println(result)
          cliCommandExecute ! CLICommandExecute.Listen(self)
        }
        case CLICommandExecute.Failed(result: String) => {
          println(result)
          println(Util.failedMessage)
          context.stop(self)
        }
        case CLICommandExecute.Exit => {
          println(Util.exitMessage)
          context.stop(self)
        }
      }
    }

I wrote ApplicationTest. But when I run it, test results failed.

    class ApplicationTest  extends TestKit(ActorSystem("testSystem"))
      with WordSpecLike
      with Matchers {

        "A application actor" must {
          // Creation of the TestActorRef
          val actorRef = TestActorRef[Application]
          val result = "success"
          "receive messages" in {
            // This call is synchronous. The actor receive() method will be called in the current thread
            actorRef ! CLICommandExecute.Done(result)
            // This method assert that the testActorRef has received a specific message
            expectMsg("success")
          }
        }
    }     

Error is as follows:

    assertion failed: timeout (3 seconds) during expectMsg while waiting for success
    java.lang.AssertionError: assertion failed: timeout (3 seconds) during expectMsg while waiting for success

How can I proceed?

Burak Dağlı
  • 512
  • 2
  • 10
  • 33

1 Answers1

0

To get message by expectMsg here you should send response not to cliCommandExecute, but to sender:

  case CLICommandExecute.Done(result: String) => {
       println(result)
       cliCommandExecute ! CLICommandExecute.Listen(self)
  }

Change it to:

 case CLICommandExecute.Done(result: String) => {
      println(result)
      sender() ! CLICommandExecute.Listen(self)
 }

and you will receive response via expectMsg.

If you want to send response not to sender but to cliCommandExecute you should pass it as constructor parameter to your Application actor:

class Application(cliCommandExecute: ActorRef) extends Actor { ...}

and in your test pass testActor when you create it. In such a way all responses will be directed to testActor and you can get them via expectMsg.

ka4eli
  • 5,294
  • 3
  • 23
  • 43
  • Thank you for your answer. But still error is given.Please, You enter command:success [INFO] [08/06/2015 15:40:09.069] [testSystem-akka.actor.default-dispatcher-2] [akka://testSystem/deadLetters] Message [com.console.app.CLICommandExecute$Listen] from TestActor[akka://testSystem/user/$$a] to Actor[akka://testSystem/deadLetters] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'. assertion failed: timeout (3 seconds) during expectMsg while waiting for success – Burak Dağlı Aug 06 '15 at 12:43
  • In normally program is working as I want to path. But I want to write test . In test there are errors – Burak Dağlı Aug 06 '15 at 12:46