如何测试依赖注入创建的actor?在我的应用程序中,我可以通过命名注入获得ActorRef:
public MyClass {
@Inject
@Named("ping")
ActorRef mPingRef;
}
如何在测试中获得此参考?
这是我的演员:
public class PingActor extends UntypedActor {
@Inject
public PingActor(Configuration configuration) {
... // Use config
}
@Override
public void onReceive(Object message) throws Exception {
if (message instanceof Ping) {
getSender().tell(new Pong(), getSelf());
}
}
public static class Ping {}
public static class Pong {}
}
我已使用自己的模块配置了我的应用程序:
public class MyModule extends AbstractModule implements AkkaGuiceSupport {
private final Configuration mConfig;
public MyModule(Environment environment, Configuration configuration){
this.mConfig = configuration;
}
@Override
protected void configure() {
bindActor(PingActor.class, "ping");
}
}
该模块在application.conf中启用:
play.modules.enabled += "com.my.package.MyModule"
答案 0 :(得分:4)
此解决方案适用于PlayScala
,但它应与PlayJava
的机制相同:
所以我得到了GuiceModule
:
class CommonModule extends AbstractModule with AkkaGuiceSupport {
override def configure(): Unit = {
bindActor[SomeActor]("actor-name")
}
}
然后测试(我从我的测试中剥离了一些东西,所以它可能无法直接编译):
import akka.actor.{ActorRef, ActorSystem}
import akka.testkit.{TestKit, TestProbe}
import module.CommonModule
import org.specs2.mutable.Specification
import org.specs2.specification.Scope
import play.api.inject._
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.test.Helpers._
class SwitchUpdateActorSpec extends Specification {
"MyActor" should {
val actorSystem = ActorSystem("test")
class Actors extends TestKit(actorSystem) with Scope
val app = new GuiceApplicationBuilder(modules = Seq(new CommonModule))
.overrides(bind[ActorSystem].toInstance(actorSystem))
.build()
"respond with 'ok' upon receiving a message" in new Actors {
running(app) {
private val injector: Injector = app.injector
private val actor: ActorRef = injector.instanceOf(BindingKey(classOf[ActorRef]).qualifiedWith("actor-name"))
val probe = TestProbe()
actor.tell("hi there!", probe.ref)
probe.expectMsg("ok")
}
}
}
}
所以我做的是:
ActorSystem
actorSystem
包裹在Akka的TestKit
(libraryDependencies += "com.typesafe.akka" %% "akka-testkit" % "2.4.1"
)GuiceApplicationBuilder
来应用覆盖app.injector
访问我的guice配置的actor 当您在bindActor
方法中查看正在使用的MyModule.configure()
的实现时,会发生什么变得非常明显:
def bindActor[T <: Actor: ClassTag](name: String, props: Props => Props = identity): Unit = {
accessBinder.bind(classOf[ActorRef])
.annotatedWith(Names.named(name))
.toProvider(Providers.guicify(Akka.providerOf[T](name, props)))
.asEagerSingleton()
}
答案 1 :(得分:2)
我正在编写演员单元测试
static ActorSystem system;
static Configuration configuration;
static MyActor myActor;
@BeforeClass
public static void setup() {
Map<String, Object> stringConf = new HashMap<>();
configuration = new Configuration(stringConf);
system = ActorSystem.apply();
final Props props = Props.create(MyActor.class, configuration);
final TestActorRef<MyActor> ref = TestActorRef.create(system, props, "myActor");
myActor = ref.underlyingActor();
}
@AfterClass
public static void teardown() {
JavaTestKit.shutdownActorSystem(system);
system = null;
}
然后你可以调用你的actor中的方法,就像它是一个普通的java类一样。根据游戏框架https://www.playframework.com/documentation/2.5.x/JavaFunctionalTest
通常最佳做法是仅在功能测试中注入成员并在单元测试中手动创建实例。
这就是我在这里做的事情。你需要依赖
"com.typesafe.akka" % "akka-testkit_2.11" % "2.4.12" % "test"
为此工作。希望这会有所帮助。