Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何使我的本地演员更易于测试?_Scala_Unit Testing_Refactoring_Akka - Fatal编程技术网

Scala 如何使我的本地演员更易于测试?

Scala 如何使我的本地演员更易于测试?,scala,unit-testing,refactoring,akka,Scala,Unit Testing,Refactoring,Akka,我有一个演员系统,大致如下: class LocalActor extends Actor { // create the remote actor val remoteActor = context.actorSelection("akka.tcp://RemoteSystem@127.0.0.1:2552/user/RemoteActor") def receive = { case foo: String => remoteActor ! s"foo = ${

我有一个演员系统,大致如下:

class LocalActor extends Actor {

  // create the remote actor
  val remoteActor = context.actorSelection("akka.tcp://RemoteSystem@127.0.0.1:2552/user/RemoteActor")

  def receive = {
    case foo: String => remoteActor ! s"foo = ${foo}"
    case bar: Int => remoteActor ! s"bar = ${bar}"
    case _ => remoteActor ! "No clue..."
  }
}
我想重构它,使
remoteActor
的TCP/IP不是硬编码的。最简单的更改是显式地将其传递给构造函数:

class LocalActor(TcpIp: String) extends Actor {

    val remoteActor = context.actorSelection(TcpIp)
    // ...
}
但我担心,在TCP/IP地址已经在使用的情况下,这可能会导致问题。对我来说最有意义的选择是将参与者(或引用或类似内容)传递给构造函数——在Akka中有没有一种惯用的方法来实现这一点

我有点困惑,因为
remoteActor
的类型是
akka.actor.ActorSelection
,我可能希望它是
actor
ActorRef

幸运的是,远程参与者只与
发送者进行交互
,因此它的方式很好;但当地演员仍然很狡猾


如果我上面的想法不是一个好主意,那么传统的方法是什么使它更通用和可测试

实现这一点的一种方法是直接将引用传递给actor类:

object LocalActor {
  def prop(remoteActor: ActorRef) = Props(new LocalActor(remoteActor))
}

class LocalActor(remoteActor: ActorRef) extends Actor {
  def receive = {
    case foo: String => remoteActor ! s"foo = ${foo}"
    case bar: Int => remoteActor ! s"bar = ${bar}"
    case _ => remoteActor ! "No clue..."
  }
}
然后,无论您在何处创建
LocalActor
,您都可以通过解析
actorSelection
来创建对
remoteActor
的引用:

val system = ActorSystem("yourSystem")
implicit val resolveTimeout = Timeout(5 seconds)
val remoteActor = Await.result(system.actorSelection("akka.tcp://RemoteSystem@127.0.0.1:2552/user/RemoteActor").resolveOne(), resolveTimeout.duration)
val localActor = system.actorOf(LocalActor.props(remoteActor), "LocalActor")
然后,为了进行测试,您只需要注入一个
TestProbe

val testProbe = TestProbe()
val testingLocalActor = system.actorOf(LocalActor.props(testProbe.ref))
val testString = "TEST"
testingLocalActor ! testString
testProbe.expectMsg(s"foo = $testString")

TestProbe
太棒了!干杯