defpotatoesOk: MatchResult[Any] = get("/foods/potatoes") { // Assert that the status of response was 200(OK) status must_== 200 }
// Specs2 syntax describes what will be asserted // using string to describe the test defis: SpecStructure = s2""" GET /foods/potatoes on FoodServlet should return status 200 $potatoesOk """
// Mounts the servlet to the root path so it can be called addServlet(classOf[FoodServlet], "/*")
}
这里面有一个奇怪的语法需要讲解下。
如果你熟悉Scala的字符串插值,如s"my name is $name", 那么对接下来的部分会更容易理解。
classFoodServletSpecextendsScalatraSpec{ defis: SpecStructure = s2""" GET /foods/potatoes on FoodServlet should return status 200 $potatoesOk should be JSON $potatoesJSON should contain name potatoes $potatoesName """
addServlet(classOf[FoodServlet], "/*")
val testURL = "/foods/potatoes"
defpotatoesOk: MatchResult[Any] = get(testURL) { status must_== 200 }
defpotatoesJSON: MatchResult[String] = get(testURL) { header("Content-Type") must startWith("application/json;") }
defpotatoesName: MatchResult[String] = get(testURL) { body must contain("{\"name\":\"potatoes\"}") }
defis: SpecStructure = s2""" GET /foods/potatoes on FoodServlet should return status 200 $potatoesOk should be JSON $potatoesJSON should contain name potatoes $potatoesName """
addServlet(classOf[FoodServlet], "/*")
val testURL = "/foods/potatoes"
defpotatoesOk: MatchResult[Any] = get(testURL) { status must_== 200 }
defpotatoesJSON: MatchResult[String] = get(testURL) { header("Content-Type") must startWith("application/json;") }
[info] FoodServletSpec [info] + GET /foods/potatoes on FoodServlet [info] should return status 200 [info] + should be JSON [info] + should contain name potatoes [info] Total for specification FoodServletSpec [info] Finished in 850 ms [info] 3 examples, 5 expectations, 0 failure, 0 error 20:00:21.390 [pool-26-thread-6] INFO o.e.j.server.handler.ContextHandler - Stopped o.e.j.s.ServletContextHandler@6b12f7dd{/,file:///D:/IdeaProjects/scala/scalatra1/src/main/webapp/,UNAVAILABLE} [info] MyScalatraServletTests: [info] - GET / on MyScalatraServlet should return status 200 [info] ScalaTest [info] Run completed in 2 seconds, 229 milliseconds. [info] Total number of tests run: 1 [info] Suites: completed 1, aborted 0 [info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0 [info] All tests passed. [info] Passed: Total 4, Failed 0, Errors 0, Passed 4 [success] Total time: 5 s, completed 2019-11-5 20:00:21
// Runs the tests sequentially because the stub is stateful sequential
val stubLauncher = newStubNukeLauncher addServlet(newNukeLauncherServlet(stubLauncher), "/*")
// Cleans up the state between test runs defafter: Unit = stubLauncher.isLaunched = false
// Factor out common logic deflaunch[A](code: String)(f: => A): A = post("/launch", "code" -> code)(f)
"The wrong pass code" should { "respond with forbidden" in { launch("wrong") { status must_== 403 } } "not launch the nukes" in { launch("wrong") { stubLauncher.isLaunched must_== false } } } "The right pass code" should { "launch the nukes" in { launch("password123") { stubLauncher.isLaunched must_== true } } } }
addServlet(classOf[FoodServlet], "/*") "GET /foods/potatoes on FoodServlet" must { "return status 200" in { get("/foods/potatoes") { status should equal(200) } } "be JSON" in { get("/foods/potatoes") { header("Content-Type") should startWith("application/json;") } } "should have name potatoes" in { get("/foods/potatoes") { jsonBody \ "name" should equal(JString("potatoes")) } } } }