Integrating Wiremock with scalatestplus.play

639 views
Skip to first unread message

Abhishek Jain

unread,
Jun 16, 2017, 1:27:06 PM6/16/17
to Play Framework
Hi,

We are trying to upgrade our code to Play 2.6

But are facing an issue when try to use wiremock. 

I am not sure if it's an issue with 

"org.scalatestplus.play" %% "scalatestplus-play" % "3.0.0-RC1" % IntegrationTest 
or 
"com.github.tomakehurst" % "wiremock" % "2.6.0" % IntegrationTest

Below are my dependencies in  build.sbt.

```
libraryDependencies ++= Seq(
  "com.github.tomakehurst" % "wiremock" % "2.6.0" % IntegrationTest,
  "org.mockito" % "mockito-core" % "1.9.0" % "test",
  "org.jsoup" % "jsoup" % "1.10.2" % "test",
  "org.scalactic" %% "scalactic" % "3.0.1" % "test, it",
  "org.scalatest" %% "scalatest" % "3.0.1" % "test, it",
  "org.scalatestplus.play" %% "scalatestplus-play" % "3.0.0-RC1" % IntegrationTest,
  guice
)
```
and a sample wire mock test

```
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpMethods, HttpRequest}
import akka.stream.ActorMaterializer
import org.scalatest.{BeforeAndAfterEach, FlatSpec, Matchers}
import com.github.tomakehurst.wiremock.WireMockServer
import com.github.tomakehurst.wiremock.client.WireMock
import com.github.tomakehurst.wiremock.client.WireMock._
import com.github.tomakehurst.wiremock.core.WireMockConfiguration._
import org.scalatest.concurrent.ScalaFutures


class ScalaTest extends FlatSpec with Matchers with BeforeAndAfterEach with ScalaFutures {
  implicit val system = ActorSystem("my-system")
  implicit val materializer = ActorMaterializer()

  val Port = 8080
  val Host = "localhost"
  val wireMockServer = new WireMockServer(wireMockConfig().port(Port))

  override def beforeEach {
    wireMockServer.start()
    WireMock.configureFor(Host, Port)
  }

  override def afterEach {
    wireMockServer.stop()
  }

  "WireMock" should "stub get request" in {
    val path = "/my/resource"
    stubFor(get(urlEqualTo(path))
      .willReturn(
        aResponse()
          .withStatus(200)))

    val request = Http().singleRequest(
      HttpRequest(
        HttpMethods.GET,
        uri = s"http://$Host:$Port$path")
    )
    whenReady(request) { response =>
      response.status.intValue() shouldBe 200
    }
  }

}
```

Now when I try to run my test. I get the below error.

```
 needed class was not found. This could be due to an error in your runpath. Missing class: org/eclipse/jetty/http/HttpGenerator$CachedHttpField
java.lang.NoClassDefFoundError: org/eclipse/jetty/http/HttpGenerator$CachedHttpField
at com.github.tomakehurst.wiremock.jetty9.JettyHttpServer.createServer(JettyHttpServer.java:117)
at com.github.tomakehurst.wiremock.jetty9.JettyHttpServer.<init>(JettyHttpServer.java:68)
at com.github.tomakehurst.wiremock.jetty9.JettyHttpServerFactory.buildHttpServer(JettyHttpServerFactory.java:31)
at com.github.tomakehurst.wiremock.WireMockServer.<init>(WireMockServer.java:73)
at ScalaTest.<init>(ScalaTest.scala:20)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at java.lang.Class.newInstance(Class.java:442)
at org.scalatest.tools.Runner$.genSuiteConfig(Runner.scala:1422)
at org.scalatest.tools.Runner$.$anonfun$doRunRunRunDaDoRunRun$8(Runner.scala:1236)
at scala.collection.immutable.List.map(List.scala:283)
at org.scalatest.tools.Runner$.doRunRunRunDaDoRunRun(Runner.scala:1235)
at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24(Runner.scala:1031)
at org.scalatest.tools.Runner$.$anonfun$runOptionallyWithPassFailReporter$24$adapted(Runner.scala:1010)
at org.scalatest.tools.Runner$.withClassLoaderAndDispatchReporter(Runner.scala:1500)
at org.scalatest.tools.Runner$.runOptionallyWithPassFailReporter(Runner.scala:1010)
at org.scalatest.tools.Runner$.run(Runner.scala:850)
at org.scalatest.tools.Runner.run(Runner.scala)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.runScalaTest2(ScalaTestRunner.java:138)
at org.jetbrains.plugins.scala.testingSupport.scalaTest.ScalaTestRunner.main(ScalaTestRunner.java:28)
Caused by: java.lang.ClassNotFoundException: org.eclipse.jetty.http.HttpGenerator$CachedHttpField
```

Strangely when I remove   

"org.scalatestplus.play" %% "scalatestplus-play" % "3.0.0-RC1" % IntegrationTest,

Everything works fine. But I cannot use GuiceOneServerPerSuite.

Please advice me if i have done something wrong or there is a bug.

Regards

Matthias Erche

unread,
Sep 15, 2017, 10:46:44 AM9/15/17
to Play Framework
Hi,

In case of someone is stumbling over this fairly old message and is interested in an answer:

Some Selenium drivers in the transitive dependencies of ScalaTest and/or ScalaTest plus Play comes with a newer version of Jetty which is not compatible with Wiremock. If fixed the issue by overriding jetty versions:

val jettyVersion = "9.2.13.v20150730"
...
dependencyOverrides ++= Set(
"org.eclipse.jetty" % "jetty-server" % jettyVersion,
"org.eclipse.jetty" % "jetty-servlet" % jettyVersion,
"org.eclipse.jetty" % "jetty-security" % jettyVersion,
"org.eclipse.jetty" % "jetty-servlets" % jettyVersion,
"org.eclipse.jetty" % "jetty-continuation" % jettyVersion,
"org.eclipse.jetty" % "jetty-webapp" % jettyVersion,
"org.eclipse.jetty" % "jetty-xml" % jettyVersion,
"org.eclipse.jetty" % "jetty-client" % jettyVersion,
"org.eclipse.jetty" % "jetty-http" % jettyVersion,
"org.eclipse.jetty" % "jetty-io" % jettyVersion,
"org.eclipse.jetty" % "jetty-util" % jettyVersion,
"org.eclipse.jetty.websocket" % "websocket-api" % jettyVersion,
"org.eclipse.jetty.websocket" % "websocket-common" % jettyVersion,
"org.eclipse.jetty.websocket" % "websocket-client" % jettyVersion

)

Hope this helps.

Best,

 Matthias
Reply all
Reply to author
Forward
0 new messages