Play Framework 2.4.x - 覆盖Guice绑定

时间:2016-05-10 16:28:03

标签: scala playframework guice

我有几个测试用例,并且有一个测试用例,我想测试通知不可用。我使用单独的GuiceInjectorBuilder将通知服务实例注入(覆盖)到None,而不是通常的Some(DefaultNotificationService)

class MySpec extends PlaySpec with Results with OneAppPerSuite {
  def appController = Application.instanceCache[AppController].apply(app)

  // typical case
  "cancel an order" should {
      "return HTTP OK" in {        
        val result: Future[Result] = injector.instanceOf[AppController].cancel(1).apply(FakeRequest())
        status(result) mustEqual OK
        (contentAsJson(result) \ "message").as[String] mustEqual "Order no. 1 is cancelled"
      }
    }

    // exception case 
    "cancel an order but notification service is OUT" should {
      import play.api.inject.bind

      val injector = new GuiceInjectorBuilder()
        .bindings(new MockAppModule)
        .in(Mode.Test)
        .overrides(bind[Option[NotificationService]].toInstance(None))  // usually it is configured to Some(DefaultNotificaionService)
        .injector()

      "return HTTP Multi Status" in {
        val result: Future[Result] = injector.instanceOf[AppController].update(1).apply(FakeRequest())
        status(result) mustEqual MULTI_STATUS
        (contentAsJson(result) \ "message").as[String] mustEqual "Order no. 1 is cancelled but user does not know"
      }
    }

  ...
  }    

它不起作用,因为MockAppModule依赖于Play在其测试的启动生命周期中注入的其他模块。如何为MockAppModule加载这些Play默认模块以适用于此测试用例?有一个更好的方法吗?感谢

1 个答案:

答案 0 :(得分:0)

如果您想针对每个测试而不是每个套件使用一个应用程序,则可以尝试像这样重写绑定(可能有与newAppForTest()等效的方法,即针对每个套件使用一个应用程序):

class MySpec extends PlaySpec with Results with GuiceOneAppPerTest {

implicit override def newAppForTest(testData: TestData): Application = {
    GuiceApplicationBuilder()
        .overrides(bind[Option[NotificationService]].toInstance(None))  // usually it is configured to Some(DefaultNotificaionService)
        .build()
    }
}