Akka - 测试执行测试的功能

时间:2014-11-23 16:55:51

标签: scala akka scalatest specs2

我有以下特质

trait MyTrait{

  def printHelloWorld(){
    println("hello world")
  }

}

case object SayHello

class MyActor extends Actor with MyTrait{

   def recieve = {
       case SayHello => printHelloWorld
   }
} 

现在我正在尝试创建单元测试,然后测试然后Say Hello Object调用打印问候消息

"My Actor" should{
   "println hello msg if SayHello sent" in{
      val myTraitMock = mock[MyTrait]

      val myActor = system.actorOf(Props(new MyActor))
      myActor ! SayHello

      Thread.sleep(500)
      there was atLeastOne(myTraitMock).printHelloMessage
   }
} 

然而,此单元测试始终为绿色。即使我用简单的println方法替换这个方法。

有没有其他方法来测试这种情况?

3 个答案:

答案 0 :(得分:2)

这个怎么样:

trait MyActor extends Actor{self:MyTrait

   def recieve = {
       case SayHello => printHelloWorld
   }
}

class MyMainActor extends MyActor with MyTrait

"My Actor" should{
"println hello msg if SayHello sent" in{
     class MockActor extends MyActor with SomeMyTrait

      val x = new MockActor
      val myActor = system.actorOf(Props(x))
      myActor ! SayHello

      Thread.sleep(500)
      there was atLeastOne(x).printHelloMessage
   }

一般来说,对于演员而言,我不喜欢上面的测试。 阿卡Test-kit很棒。我强烈建议看一下。

我会做的:

trait MyTrait{

  def printHelloWorld(){
    println("hello world")

  }

}

case object SayHello
case object Printed

class MyActor extends Actor with MyTrait{

   def recieve = {
       case SayHello => printHelloWorld
                        sender ! Printed
   }
} 

import akka.actor.ActorSystem
import akka.testkit.{ TestProbe, ImplicitSender, TestKit }
import org.scalatest.matchers.ShouldMatchers
import org.scalatest.{ BeforeAndAfterAll, FunSuite }    
import scala.concurrent.duration._

class MyTest extends TestKit(ActorSystem("MyTest1"))
  with FunSuite
  with BeforeAndAfterAll
  with ShouldMatchers
  with ImplicitSender{

  override def afterAll() { system.shutdown() }
  test("MyTrait is called when triggered") {
    val x = TestProbe()
    val myActor = system.actorOf(Props(new MyActor))
    myActor.send(x, SayHello)
    x.expectMsg(Printed)

}

答案 1 :(得分:1)

我知道这是一个老问题,但我有相同的用例(火灾和遗忘),我想出了一个使用Probe的简单解决方案:

case object SayHello

class MyActor(f: () => Unit) extends Actor{ // pass function as a parameter
  def receive = {
    case SayHello => f()
  }
}

现在,如果你想创建一个测试:

  "test" {
    val probe = TestProbe()

    case object Executed

    def mockF():Unit = {
      println("test")
      probe.ref ! Executed
    }

    val testActor = TestActorRef(Props(new MyActor(mockF)))
    testActor ! SayHello
    //probe.expectMsg blocks the thread, so it'll wait for Executed message.
    probe.expectMsgPF(){case  Executed => 1}

  }

如果您不想将函数作为参数传递,那么您可以使用特征执行相同的操作:

trait MyTraitImpl extends MyTrait{
  def printHelloWorld(){
    println("hello world")
      }
}

trait MyTrait{
  def printHelloWorld()
}

case object SayHello

class MyActor extends Actor{
  myTrait:MyTrait =>

  def receive = {
    case SayHello => printHelloWorld
  }
}

并测试:

  "test" {
    val probe = TestProbe()

    case object Executed

    trait MyTraitMock extends MyTrait{
      def printHelloWorld(){
        println("hello world")

        probe.ref ! Executed
      }
    }

    val testActor = TestActorRef(Props(new MyActor() with MyTraitMock))
    testActor ! SayHello

    probe.expectMsgPF(){case  Executed => 1}

  }

答案 2 :(得分:0)

您可以测试打印到EventFilter的内容。所以如果你的演员会打印这样的信息:

case _ => log.info(printMessage)

然后你可以测试

EventFilter.info(start="hello world", occurences=1).intercept {
  MyActor ! SayHello
}