java - 如何使用 akka BehaviourTestKit 从类型化上下文测试非类型化 Actor 部署?

标签 java scala akka akka-typed

我正在开发类型化的 akka 应用程序,由于某种原因,我需要使用类型化上下文中的非类型化参与者。

我编写了一个简单的测试来尝试BehaviorTestKit并输入akka testkit。对于类型化的 Actor ,它可以工作,但对于具有非类型化子级的 Actor ,我会收到“仅允许改编的非类型化ActorContext”错误。

这是父 Actor :

public class AppGuardianTest extends AbstractBehavior<String> {
    private ActorContext context;

    public AppGuardianTest(ActorContext context) {
        this.context = context;

        ActorRef child = Adapter.actorOf(context, SomeUntypedActor.props(), "child");     
    }
    @Override
    public Receive<String> createReceive() {
        return receiveBuilder()
                .onMessage(String.class, m -> Behaviors.same())
                .onSignal(PostStop.class, signal -> postStop()).build();
    }
    private Behavior<String> postStop() {
        context.getLog().info("Application stopped");
        return this;
    }
    public static Behavior behavior() {
        return Behaviors.setup(AppGuardianTest::new);
    }
}

童星

public class SomeUntypedActor extends AbstractActor {
    public static Props props() {
        return Props.create(SomeUntypedActor.class);
    }

    @Override
    public Receive createReceive() {
        return receiveBuilder().matchAny(m -> {
            System.out.println(m);
        }).build();
    }
}

和测试

import akka.actor.testkit.typed.scaladsl.{BehaviorTestKit, ScalaTestWithActorTestKit}
import some.test.AppGuardianTest
import org.scalatest.WordSpecLike
class AppGuardianSpec extends ScalaTestWithActorTestKit with WordSpecLike {

  "appGuardian" should {
    "deploy child" in {
      val testKit = BehaviorTestKit(AppGuardianTest.behavior())
      val child = testKit.childInbox[String]("child")
    }
  }
}

异常(exception):

only adapted untyped ActorContext permissible (Inbox(Actor[akka.actor.typed.inbox://anonymous/testkit#1338528633]) of class akka.actor.testkit.typed.internal.EffectfulActorContext)
java.lang.UnsupportedOperationException: only adapted untyped ActorContext permissible (Inbox(Actor[akka.actor.typed.inbox://anonymous/testkit#1338528633]) of class akka.actor.testkit.typed.internal.EffectfulActorContext)
    at akka.actor.typed.internal.adapter.ActorContextAdapter$.toUntypedImp(ActorContextAdapter.scala:110)
    at akka.actor.typed.internal.adapter.ActorContextAdapter$.toUntyped(ActorContextAdapter.scala:125)
    at akka.actor.typed.javadsl.Adapter$.actorOf(Adapter.scala:88)
    at akka.actor.typed.javadsl.Adapter.actorOf(Adapter.scala)
    at some.test.AppGuardianTest.<init>(AppGuardianTest.java:15)
    at akka.actor.typed.javadsl.Behaviors$.$anonfun$setup$1(Behaviors.scala:43)
    at akka.actor.typed.Behavior$DeferredBehavior$$anon$1.apply(Behavior.scala:239)
    at akka.actor.typed.Behavior$.start(Behavior.scala:324)
...

最佳答案

我发现的唯一方法是使用无类型的 akka TestKit 而不是 BehaviourTestKit。但是您还需要在某个地方存储指向子项的链接,例如在静态字段中(当然在某些情况下这是不合适的)

    "appGuardian" should {
    "deploy child" in {
      val AppG = Adapter.spawn(system, AppGuardianTest.behavior(), "app_g")

      val actor = Await.result(Future {
        while (AppGuardianTest.child == null) {
          Thread.sleep(100)
        }
        AppGuardianTest.child
      }(ExecutionContext.global), new FiniteDuration(5, TimeUnit.SECONDS))      

    }
  }

我认为这不是最好的方法,但却是最简单的方法之一。另一种方法是扩展 Actor 的协议(protocol)并添加包含子 Actor 的消息,并向 AppGuardian 询问子 Actor。

关于java - 如何使用 akka BehaviourTestKit 从类型化上下文测试非类型化 Actor 部署?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54633342/

相关文章:

java - 表单提交thymeleaf和Spring boot后如何保持在同一页面?

java - 由于类型安全版本存储库中的校验和无效,无法使用 guava 依赖项进行部署

akka - 在 Akka (Java) 中,我如何让我的主管记录捕获的任何异常?

java - 从 java.util.concurrent.Future<T> 到 play.libs.F.Promise<T> : How to do that in Java?

scala - 从第二个元素开始的 foldLeft 的替代

scala - 无法压缩分区数不相等的 RDD。我可以使用什么来替代 zip?

scala - 如何让 Scalaz ZIO 变得懒惰?

Scala:Akka actor 不会死在 Play Framework 2.2.0 中

scala - 在 Akka 中暂停 Actor

java - 在 android 中重绘位图的更快方法?