Hi all. Second of two posts about some newcomer-ish problems getting my sea legs with akka-http. As the library is new and the documentation evolving, I'm hoping the answers will be useful to other folks! Here is problem number 2.
I am trying to test this route:
object Main extends App with Config {
import system.dispatcher
implicit val system = ActorSystem("whereat-server")
implicit val materializer = ActorMaterializer()
def echo (loc: Location)(completer: Location ⇒ Unit) = completer(loc)
val route =
path("hello") {
get {
complete {
"hello world!" }
}
} ~
path("locations") {
post {
entity(as[Location]) { loc ⇒
completeWith(instanceOf[Location]) {
completer ⇒ echo(loc)(completer)
}
}
}
}
Http().bindAndHandle(route, httpInterface, httpPort)
println(s"Server online at http://localhost:$httpPort")
}
With these specs:
import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.testkit.ScalatestRouteTest
import org.scalatest.{Matchers, WordSpec}
import support.SampleData
class MainSpec extends WordSpec with Matchers with ScalatestRouteTest {
lazy val route = Main.route
lazy val s17 = SampleData.s17
lazy val s17Json = SampleData.s17Json
"The service" should {
"respond to GET/hello with 'hello world!'" in {
Get("/hello") ~> route ~> check {
responseAs[String] shouldEqual "hello world!"
}
}
"respond to a properly formated POST/locations with echo" in {
Post("/locations", HttpEntity(`application/json`, s17Json)) ~> route ~> check {
responseAs[String] shouldEqual s17Json
}
}
}
}
Using the route test in the examples from the
akka-http docs on the `example` directive as my template for the test with the JSON route.
When I run the code from Main using foreman (locally) or remotely on Heroku, it works as expected. The "/hello" route says "hello world!" and the "/locations" endpoint echoes back a Location JSON object.
However, when I try to run my specs, a couple of bizarre things are happening:
(1) The test for the "hello" route fails because the actual response is an internal server error. (Despite the fact that this isn't true running the live code!) And I get the following error messages:
[ERROR] [07/10/2015 23:52:50.540] [ScalaTest-run-running-MainSpec] [ActorSystem(MainSpec)] Error during processing of request HttpRequest(HttpMethod(GET),http://example.com/hello,List(),HttpEntity.Strict(none/none,ByteString()),HttpProtocol(HTTP/1.1))
java.lang.NullPointerException
at akka.http.scaladsl.server.directives.ExecutionDirectives$$anonfun$handleExceptions$1$$anonfun$apply$1.apply(ExecutionDirectives.scala:27)
at akka.http.scaladsl.server.directives.ExecutionDirectives$$anonfun$handleExceptions$1$$anonfun$apply$1.apply(ExecutionDirectives.scala:23)
at akka.http.scaladsl.testkit.RouteTest$TildeArrow$$anon$1.apply(RouteTest.scala:132)
at akka.http.scaladsl.testkit.RouteTest$TildeArrow$$anon$1.apply(RouteTest.scala:120)
at akka.http.scaladsl.testkit.RouteTest$WithTransformation2.$tilde$greater(RouteTest.scala:101)
at MainSpec$$anonfun$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(MainSpec.scala:21)
at MainSpec$$anonfun$1$$anonfun$apply$mcV$sp$1.apply(MainSpec.scala:21)
at MainSpec$$anonfun$1$$anonfun$apply$mcV$sp$1.apply(MainSpec.scala:21)
(... truncated ...)
"[There was an internal server error.]" did not equal "[hello world!]"
ScalaTestFailureLocation: MainSpec$$anonfun$1$$anonfun$apply$mcV$sp$1$$anonfun$apply$mcV$sp$2 at (MainSpec.scala:22)
org.scalatest.exceptions.TestFailedException: "[There was an internal server error.]" did not equal "[hello world!]"
at org.scalatest.MatchersHelper$.newTestFailedException(MatchersHelper.scala:160)
at org.scalatest.Matchers$AnyShouldWrapper.shouldEqual(Matchers.scala:6303)
at MainSpec$$anonfun$1$$anonfun$apply$mcV$sp$1$$anonfun$apply$mcV$sp$2.apply$mcV$sp(MainSpec.scala:22)
at MainSpec$$anonfun$1$$anonfun$apply$mcV$sp$1$$anonfun$apply$mcV$sp$2.apply(MainSpec.scala:22)
at MainSpec$$anonfun$1$$anonfun$apply$mcV$sp$1$$anonfun$apply$mcV$sp$2.apply(MainSpec.scala:22)
at scala.util.DynamicVariable.withValue(DynamicVariable.scala:58)
Totally stumped!
(2) I get a compile error for the backtick notation used in
`application/json`. Not too surprising as that's a bit black-magic-looking. I'm okay with using another way
to specify this is a JSON request, I just can't find any in the docs.
Can anyone help? Very much want to put this amazing new library into play on my project and evangelize like crazy for akka-stream at
Recurse Center, but having a hard time getting out of the gates. Show some love?
/a/