如何测试依赖注入创建的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"
这个解决方案适用于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
当您查看在MyModule.configure()方法中使用的bindActor的实现时,会发生很明显的情况:
- 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()
- }