akka-http-testkit route produces "internal service error" but live route works (?!?)

720 views
Skip to first unread message

Austin Guest

unread,
Jul 11, 2015, 5:22:44 AM7/11/15
to akka...@googlegroups.com
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/

Johannes Rudolph

unread,
Jul 12, 2015, 11:15:25 AM7/12/15
to akka...@googlegroups.com
Hi Austin,


On Saturday, July 11, 2015 at 11:22:44 AM UTC+2, Austin Guest wrote:
(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:

That's probably because you are relying on a `val` that is defined inside an `App` class which extends from `DelayedInit` which has surprising semantics. Try making `route` a `def`.
 
(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.

It's hard to say because you are not providing any details about the error or the types of object you try to pass in otherwise. Have you imported `application/json` from somewhere? Try `akka.http.scaladsl.model.MediaTypes.`application/json``.

HTH
Johannes
Reply all
Reply to author
Forward
0 new messages