import org.specs2.Specification
import org.specs2.mock.Mockito
import org.scalatra.test.ScalatraTests
import org.eclipse.jetty.testing.ServletTester
import org.specs2.specification.After
class MySpec extends Specification { def is =
"My spec must" ^
"verify that scalatra can be tested" ! Specs().assert()
/**
* Create a new jetty context each time
* This lets us mock expectations *per* specification
*/
case class Specs() extends After with ScalatraTests with Mockito {
// The servlet tester gives an http context to your tests
lazy val tester = new ServletTester
tester.start()
val myMock = mock[MyObject]
// Register your servlet with the context and inject the mock
addServlet(new MyServlet(myMock), "/*")
// don't leave the jetty context hanging around
def after { tester.stop() }
// Pay special attention to the "this" keyword, which will provide the
// ...method in a scope such that "after" may be called for teardown
def assert() = this {
// Just some expectation on the mock object
myMock.get(0) returns true
get("/") {
there was one(myMock).get(0)
}
}
}
}
Comments
I think you're misleading the people with this snippet.
This will create a new server instance for ever example you execute. The tester should be started before all examples execute and stop afterwards.
https://github.com/scalatra/scalatra/blob/develop/specs2/src/main/scala/org/scalatra/test/specs2/BaseScalatraSpec.scala#L16
And the way you use this then:
https://github.com/scalatra/scalatra/blob/develop/specs2/src/test/scala/org/scalatra/test/specs2/ScalatraSpecSpec.scala
you can get that by depending on scalatra-specs2
In regard to creating a new server instance, the Spec that you reference does not get the full idea across of the problem above. Specifically, if your servlet depends on a mock object, then you cannot rely on the same servlet in each test as the injected mock object must be distinct per fragment. I did not originally have this in my code example and will update it to reflect this.
Please correct if I am wrong.