An example of general approach for integration testing can be found here:
https://github.com/scaldi/scaldi-play-example/blob/master/test/IntegrationSpec.scala#L22
It's not direct equivalent though, since it uses HttpUnit
instead of WSClient
. More precise equivalent would be something like this:
import scaldi.play.ScaldiApplicationBuilder._
import scaldi.Injectable._
val fakeRotes = FakeRouterModule {
case ("GET", "/repositories") => Action {
Results.Ok(Json.arr(Json.obj("full_name" -> "octocat/Hello-World")))
}
}
withScaldiInj(modules = fakeRotes :: Nil) { implicit inj ⇒
val client = inject [WSClient]
withTestServer(inject [Application]) { port ⇒
val result = Await.result(
new GitHubClient(client, s"http://localhost:$port").repositories(), 10.seconds)
result must_== Seq("octocat/Hello-World")
}
}
It uses a WSClient
, just like in your example. The difference is that Application
and WSClient
are injected and test does not rely on a global state or factories.
In order to use this example you also need this small helper function which creates a test server based on the injected Application
:
def withTestServer[T](application: Application, config: ServerConfig = ServerConfig(port = Some(0), mode = Mode.Test))(block: Port => T)(implicit provider: ServerProvider): T = {
val server = provider.createServer(config, application)
try {
block(new Port((server.httpPort orElse server.httpsPort).get))
} finally {
server.stop()
}
}
Play already provides some helper functions out-of-the-box to create a test server, but most of them either reinitialize an application of rely on Guice. That's because you need to create your own simplified version of it. This function is probably a good candidate for inclusion in scaldi-play.