playframework – 在play framework 2.4.x中使用依赖注入测试actor

前端之家收集整理的这篇文章主要介绍了playframework – 在play framework 2.4.x中使用依赖注入测试actor前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如何测试依赖注入创建的actor?在我的应用程序中,我可以通过命名注入获得ActorRef:
  1. public MyClass {
  2. @Inject
  3. @Named("ping")
  4. ActorRef mPingRef;
  5. }

如何在我的测试中获得此参考?

这是我的演员:

  1. public class PingActor extends UntypedActor {
  2. @Inject
  3. public PingActor(Configuration configuration) {
  4. ... // Use config
  5. }
  6.  
  7.  
  8. @Override
  9. public void onReceive(Object message) throws Exception {
  10. if (message instanceof Ping) {
  11. getSender().tell(new Pong(),getSelf());
  12. }
  13. }
  14.  
  15. public static class Ping {}
  16. public static class Pong {}
  17. }

我已经使用自己的模块配置了我的应用程序:

  1. public class MyModule extends AbstractModule implements AkkaGuiceSupport {
  2. private final Configuration mConfig;
  3.  
  4. public MyModule(Environment environment,Configuration configuration){
  5. this.mConfig = configuration;
  6. }
  7.  
  8. @Override
  9. protected void configure() {
  10. bindActor(PingActor.class,"ping");
  11. }
  12. }

该模块在application.conf中启用:

  1. play.modules.enabled += "com.my.package.MyModule"
这个解决方案适用于PlayScala,但它应该与PlayJava的机制相同:

所以我得到了我的GuiceModule:

  1. class CommonModule extends AbstractModule with AkkaGuiceSupport {
  2. override def configure(): Unit = {
  3. bindActor[SomeActor]("actor-name")
  4. }
  5. }

然后测试(我从我的测试中删除了一些东西,所以它可能无法直接编译):

  1. import akka.actor.{ActorRef,ActorSystem}
  2. import akka.testkit.{TestKit,TestProbe}
  3. import module.CommonModule
  4. import org.specs2.mutable.Specification
  5. import org.specs2.specification.Scope
  6. import play.api.inject._
  7. import play.api.inject.guice.GuiceApplicationBuilder
  8. import play.api.test.Helpers._
  9.  
  10. class SwitchUpdateActorSpec extends Specification {
  11.  
  12. "MyActor" should {
  13.  
  14. val actorSystem = ActorSystem("test")
  15. class Actors extends TestKit(actorSystem) with Scope
  16.  
  17. val app = new GuiceApplicationBuilder(modules = Seq(new CommonModule))
  18. .overrides(bind[ActorSystem].toInstance(actorSystem))
  19. .build()
  20.  
  21.  
  22. "respond with 'ok' upon receiving a message" in new Actors {
  23. running(app) {
  24. private val injector: Injector = app.injector
  25. private val actor: ActorRef = injector.instanceOf(BindingKey(classOf[ActorRef]).qualifiedWith("actor-name"))
  26.  
  27. val probe = TestProbe()
  28. actor.tell("hi there!",probe.ref)
  29.  
  30. probe.expectMsg("ok")
  31. }
  32. }
  33. }
  34. }

所以我做的是:

>创建一个全新的ActorSystem
>将该actorSystem包装在Akka的TestKit中(libraryDependencies =“com.typesafe.akka”%%“akka-testkit”%“2.4.1”)
>使用GuiceApplicationBuilder应用覆盖
>然后直接使用app.injector访问我的guice配置的actor

当您查看在MyModule.configure()方法中使用的bindActor的实现时,会发生很明显的情况:

  1. def bindActor[T <: Actor: ClassTag](name: String,props: Props => Props = identity): Unit = {
  2. accessBinder.bind(classOf[ActorRef])
  3. .annotatedWith(Names.named(name))
  4. .toProvider(Providers.guicify(Akka.providerOf[T](name,props)))
  5. .asEagerSingleton()
  6. }

猜你在找的设计模式相关文章