2016-11-30 2 views
0

Я пытаюсь высмеять веб-сервис, используя WsTestClient, предоставленный платформой Play.com.google.inject.CreationException с функциональным тестом с использованием WSTestClient из Play Framework

нагнетание WsTestClient экземпляр в тестовой Play приложения, казалось, прямо вперед:

import javax.inject.Inject 

import org.scalatest.FunSuite 
import play.api.inject.guice.GuiceApplicationBuilder 
import play.core.server.Server 
import play.api.routing.sird._ 
import play.api.mvc._ 
import play.api.libs.json._ 
import play.api.test._ 
import play.api.inject._ 
import play.api.libs.ws.WSClient 
import scala.concurrent.Await 

class Service @Inject()(wsClient:WSClient) { 
    def query = wsClient.url("/service").get() 
} 

class WebServiceMockingRequestSuite extends FunSuite { 

    test("Webservice request") { 

    Server.withRouter() { 
     case GET(p"/service") => Action { 
      Results.Ok(JsNumber(42)) 
     } 
     } { implicit port => 
     WsTestClient.withClient { client => 

      val app = GuiceApplicationBuilder().bindings(bind[WSClient].to(client)) 
      val service = app.injector.instanceOf[Service] 

      import concurrent.duration._ 
      val response = Await.result(service.query,3.seconds) 
      assert(response.body == "42") 
     } 
     } 
    } 
} 

Но при пробном запуске приложения, я столкнулся за исключением следующего:

[info] - Mocked webservice request *** FAILED *** 
[info] com.google.inject.CreationException: Unable to create injector, see the following errors: 
[info] 
[info] 1) A binding to play.api.libs.ws.WSClient was already configured at playsample.webservice.tests.WebServiceMockingRequestSuite$$anonfun$1$$anonfun$apply$mcV$sp$2$$anonfun$apply$1.apply(WebServiceMockingTestSuite.scala:32): 
[info] Binding(interface play.api.libs.ws.WSClient to ProviderTarget([email protected])) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1). 
[info] at play.api.libs.ws.ahc.AhcWSModule.bindings(AhcWS.scala:374): 
[info] Binding(interface play.api.libs.ws.WSClient to ProviderConstructionTarget(class play.api.libs.ws.ahc.WSClientProvider) in interface javax.inject.Singleton) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1) 
[info] 
[info] 1 error 
[info] at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:466) 
[info] at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155) 
[info] at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107) 
[info] at com.google.inject.Guice.createInjector(Guice.java:96) 
[info] at com.google.inject.Guice.createInjector(Guice.java:84) 
[info] at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:181) 
[info] at playsample.webservice.tests.WebServiceMockingRequestSuite$$anonfun$1$$anonfun$apply$mcV$sp$2$$anonfun$apply$1.apply(WebServiceMockingTestSuite.scala:33) 
[info] at playsample.webservice.tests.WebServiceMockingRequestSuite$$anonfun$1$$anonfun$apply$mcV$sp$2$$anonfun$apply$1.apply(WebServiceMockingTestSuite.scala:30) 
[info] at play.api.test.WsTestClient$class.withClient(WSTestClient.scala:79) 
[info] at play.api.test.WsTestClient$.withClient(WSTestClient.scala:87) 

Интересно отметить, что все работает нормально, если экземпляр WSTestClient непосредственно впрыскивается следующим образом:

test("Webservice request without service instance") { 

    Server.withRouter() { 
     case GET(p"/service") => Action { 
     Results.Ok(JsNumber(42)) 
     } 
    } { implicit port => 

     WsTestClient.withClient { client => 

     val app = GuiceApplicationBuilder().bindings(bind[WSClient].to(client)) 

     import concurrent.duration._ 
     val response = Await.result(client.url("/service").get(),3.seconds) 
     assert(response.body == "42") 
     } 
    } 
} 

Этот тест проходит, как ожидалось, без исключения com.google.inject.CreationException.

+0

Если все, что вам нужно, что 'под клиента, зачем создавать все приложения? – rethab

+0

Идея заключалась в том, что все приложение (созданное с помощью GuiceApplicationBuilder) может затем взаимодействовать с веб-службой, запущенной на случайном порту через 'Server.withRouter()'. С тех пор я нашел [play-mockws] (https://github.com/leanovate/play-mockws), который отлично справляется с издевательством внешних ответов веб-сервисов. –

ответ

0

После того, как вы прочитали больше на странице Testing with Guice из документации Play Framework, я смог исправить эту проблему.

После подсказки, приведенной в заброшенном выражении выше (A binding to play.api.libs.ws.WSClient was already configured), я заменил

val app = GuiceApplicationBuilder().bindings(bind[WSClient].to(client)) 

с

val app = GuiceApplicationBuilder().overrides(bind[WSClient].to(client)) 

сделать тестовую работу, как и ожидалось.

Следующий тест работает хорошо в настоящее время:

import javax.inject.Inject 

import org.scalatest.FunSuite 
import play.api.inject.guice.GuiceApplicationBuilder 
import play.core.server.Server 
import play.api.routing.sird._ 
import play.api.mvc._ 
import play.api.libs.json._ 
import play.api.test._ 
import play.api.inject._ 
import play.api.libs.ws.WSClient 
import scala.concurrent.Await 

class Service @Inject()(wsClient:WSClient) { 
    def query = wsClient.url("/service").get() 
} 

class WebServiceMockingRequestSuite extends FunSuite { 

    test("Webservice request") { 

    Server.withRouter() { 
     case GET(p"/service") => Action { 
      Results.Ok(JsNumber(42)) 
     } 
     } { implicit port => 
     WsTestClient.withClient { client => 

      val app = GuiceApplicationBuilder().overrides(bind[WSClient].to(client)) 
      val service = app.injector.instanceOf[Service] 

      import concurrent.duration._ 
      val response = Await.result(service.query,3.seconds) 
      assert(response.body == "42") 
     } 
     } 
    } 
} 
Смежные вопросы