Отключить синглтон при тестировании с ScalaTest в Play для Scala

У меня есть следующее @Singleton в моем приложении Play for Scala, которое загружается при запуске:

@Singleton
class Scheduler @Inject()(@Named("mainEtl") mainEtl: ActorRef, system: ActorSystem) {

// some code  
}

Это модуль, в котором объявлен планировщик. Модуль включен в application.conf:

class Module extends AbstractModule {
  def configure() = {
    bind(classOf[Scheduler]).asEagerSingleton
  }
}

И определение соответствующего модуля для настройки @Named введенный объект, также объявленный в application.conf:

class AkkaBindings extends AbstractModule with AkkaGuiceSupport {
   def configure = {
     bindActor[MainEtl]("mainEtl")
  }
}

Когда я запускаю любой тест ScalaTest, по-видимому, запускается синглтон, потому что я получаю сообщение об ошибке, что он не находит MainEtl (объект вводится в Scheduler учебный класс). Дело в том, что мне не нужно запускать синглтон для моих тестов, поэтому мне нужно отключить его.

Вот как я вызываю приложение Play в своих тестах:

class ManageBanksTest extends PlaySpec with OneAppPerSuite with MockitoSugar {

  implicit override lazy val app = new GuiceApplicationBuilder().build

   // more test code  
}

Вот как я пытался отключить его, но он не работает, так как я получаю ту же ошибку:

  implicit override lazy val app = new GuiceApplicationBuilder()
    .disable[Scheduler]
    .build

В качестве альтернативы, я мог бы издеваться Scheduler, но я должен был бы высмеять также @Named Впрыскиваемый объект, и я не мог найти информацию о том, как этого добиться.

Есть идеи?

2 ответа

Решение

Это решение: отключить класс Module, чтобы не объявлять планировщик как singleton:

implicit override lazy val app = new GuiceApplicationBuilder()
    .disable[Module]
    .build
   import com.google.inject.AbstractModule
   import com.google.inject.name.Names 
   import org.specs2.mock.Mockito
   import play.api.inject.guice.{GuiceApplicationBuilder, GuiceableModule} 

   val modules = Option(new AbstractModule {
       override def configure() = {
         val mockMainETL = mock[MainEtl]
         bind(classOf[ActorRef])
         .annotatedWith(Names.named("mainEtl"))
         .toInstance(mockMainETL)


       val mock1 = mock[ManageBanksDAO]
       mock1.readMany answers { _ => Future{seqMany}}
       val mockManageBanks = mock[ManageBanks]
       bind(classOf[ManageBanks]).toInstance(new ManageBanks(mock1))
       }
    })
    lazy val app = new GuiceApplicationBuilder()
    .overrides(modules.map(GuiceableModule.guiceable).toSeq: _*)
    .build

Попробуйте настроить макет внутри модулей и добавить эти модули во время инициализации приложения. Это будет вводить пользовательские макеты.

Также вместо этого:

val controller = new ManageBanks(mock1)

Попробуй это:

 val controller = app.injector.instanceOf(classOf[ManageBanks])
Другие вопросы по тегам