如何使用工厂作为接收器测试Actors值

时间:2015-07-21 13:43:35

标签: scala akka

假设我有一个名为TestedActor的actor,它能够保存Int值并将其发送回如下:

run()

在我的测试中,我希望能够得到这个整数并测试它。

所以我一直在考虑创建类似的东西:

class TestedActor extends Actor {
  override def receive = receive(0)

  def receive(number: Int): Receive = {
    case new_number: Int => context.become(receive(new_number))
    case ("get", ref: ActorRef) => ref ! number
  }
}

这样,我就可以创建这个TestingPositive actor,获取TestedActor中的数字并在checkNumber中测试它。

它似乎运作良好,我的问题是:

当测试失败时,它会在actor线程中引发异常,我可以看到控制台出了什么问题,但它仍然说我的所有测试都成功了。因为(我认为)主线程没有意识到这种失败。

有人知道比所有TestingActor更简单的方法吗?

或告诉主线程失败的任何解决方案?

谢谢

1 个答案:

答案 0 :(得分:3)

使用TestKit docs here查看。你可以为你的演员写一个更简单的测试。看看你喜欢这个测试:

import akka.actor.{Props, ActorSystem}
import akka.testkit.{TestProbe, TestKit}

import org.scalatest.{BeforeAndAfterAll, FlatSpecLike, ShouldMatchers}

class ActorSpecs extends TestKit(ActorSystem("TestSystem"))
  with FlatSpecLike
  with ShouldMatchers
  with BeforeAndAfterAll {

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

  def fixtures = new {
    val caller = TestProbe()
    val actorUnderTest = system.actorOf(Props[TestedActor], name = "testedActor")
  }

  "The TestedActor" should "pass a good test" in {
    val f = fixtures; import f._

    caller.send(actorUnderTest, 42)
    caller.send(actorUnderTest, ("get", caller.ref))
    caller.expectMsg(42)
  }

  "The TestedActor" should "fail a bad test" in {
    val f = fixtures; import f._

    caller.send(actorUnderTest, 42)
    caller.send(actorUnderTest, ("get", caller.ref))
    caller.expectMsg("this won't work")
  }
}

另外,您应该了解sender。虽然您的get肯定有效,但更清晰的方法可能是回复发送方:

def receive(number: Int): Receive = {
  case new_number: Int => context.become(receive(new_number))
  case "get" => sender ! number
}

测试成为:

"The TestedActor" should "pass a good test" in {
  val f = fixtures; import f._

  caller.send(actorUnderTest, 42)
  caller.send(actorUnderTest, "get")
  caller.expectMsg(42)
}

最后,我将无耻地插入my recent blog post关于维护我的团队的akka​​代码库。我觉得在道德上有义务为新的hAkker提供阅读它的机会。 :)