[英]How to test an untyped actor deployment from a typed context using akka BehaviorTestKit?
I'm working on typed akka application and for some reason, I need to use untyped actors from typed context.我正在研究类型化 akka 应用程序,出于某种原因,我需要使用类型化上下文中的非类型化参与者。
I wrote a simple test to try BehaviorTestKit and typed akka testkit.我写了一个简单的测试来尝试 BehaviorTestKit 并输入 akka testkit。 For typed actors it works but for an actor with untyped child I get "only adapted untyped ActorContext permissible " error.
对于有类型的演员,它有效,但对于具有无类型孩子的演员,我会收到“仅适用于无类型的 ActorContext 允许”错误。
Here is the parent 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);
}
}
The child actor童星
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();
}
}
and the test和测试
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)
...
The only way I have found is to use untyped akka TestKit instead of BehaviorTestKit.我发现的唯一方法是使用无类型的 akka TestKit 而不是 BehaviorTestKit。 But you also need to store a link to a child somewhere, for instance in a static field (of course it cold be inappropriate in some situations)
但是你还需要在某个地方存储一个孩子的链接,例如在一个静态字段中(当然在某些情况下它是不合适的)
"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))
}
}
I think it is not the best but one of the easiest way.我认为这不是最好的,而是最简单的方法之一。 Another way is to extend actor's protocol and add message with a child inside and ask AppGuardian for the child actor.
另一种方法是扩展actor的协议并在里面添加带有子actor的消息并向AppGuardian询问子actor。
I have run into this same error.我遇到了同样的错误。 In the source code I have a typed actor and inside that one I want to spawn a classic actor.
在源代码中,我有一个类型化的 actor,在其中我想生成一个经典的 actor。 The child actor is being spawned from a classic system (this system was already in place) Writing the tests I was using the ScalaTestWithActorTestKit because I want to test a typed actor, but then the actor system being used is was typed one, when the source code expects a classic one.
子actor是从一个经典系统中产生的(这个系统已经到位)编写测试我使用ScalaTestWithActorTestKit是因为我想测试一个类型化的actor,但是正在使用的actor系统是类型化的,当源代码需要一个经典的。 That's why going back to the classic testKit allows the test to work
这就是为什么回到经典的 testKit 允许测试工作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.