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

Scala 如何使用工厂作为接收器测试Actors值,scala,akka,Scala,Akka,假设我有一个名为TestedActor的参与者,它可以保存一个Int值并按如下方式发送回去: 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: Act

假设我有一个名为TestedActor的参与者,它可以保存一个Int值并按如下方式发送回去:

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
  }
}
在我的测试中,我希望能够得到这个整数并测试它

所以我一直在考虑创造一些东西,比如:

class ActorsSpecs extends FlatSpec with Matchers {

  case class TestingPositive(testedActor: ActorRef) extends Actor {
    override def receive = {
      case number: Int => checkNumber(number)
      case "get" => testedActor ! ("get", self)
    }

    def checkNumber(number: Int) = {
      number should be > 0
    }
  }

  implicit val system = ActorSystem("akka-stream")
  implicit val flowMaterializer = ActorMaterializer()

  val testedActor = system.actorOf(Props[TestedActor], name = "testedActor")
  val testingActor = system.actorOf(Props(new TestingPositive(testedActor)), name = "testingActor")

  testingActor ! "get"
}
这样,我就可以创建这个TestingPositive参与者,在testedator中获取数字,并在checkNumber中测试它

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

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

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

或者有什么解决方案可以告诉主线程它失败了


谢谢你

看看如何使用
TestKit
。您可以为您的参与者编写一个简单得多的测试。看看你喜欢这个测试吗:

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")
  }
}
此外,您还应该了解
发送者
。虽然您的
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)
}

最后,我将无耻地与我的团队一起维护akka代码库。我觉得在道义上有义务给一个新客家人一个阅读的机会

谢谢,很好用!我不知道“寄件人”的事!我会读你的博客;)