Testing Rejection Handling in Akka-Http

Knoldus Inc.
Knoldus - Technical Insights
3 min readDec 27, 2016

In my previous blog, I discussed how to handle rejections in Akka Http.
You may find it here. We left it on terms to explain the testing of it later. Keeping the promise ;)

In this blog, we will learn how to be able to write the test cases for rejection handling in Akka-Http.
We will be using Akka TestKit and Akka-Http TestKit.
Dependencies are as follows:

"com.typesafe.akka" %% "akka-testkit" % "2.4.16"
"com.typesafe.akka" %% "akka-http-testkit" % "10.0.1"

Suppose we have a rejection builder

implicit def rejectionHandler =
RejectionHandler.newBuilder()
.handle { case MissingQueryParamRejection(param) =>
val errorResponse = write(ErrorResponse(BadRequest.intValue, "Missing Parameter", s"The required $param was not found."))
complete(HttpResponse(BadRequest, entity = HttpEntity(ContentTypes.`application/json`, errorResponse)))
}
.result()

and a route

path("check") {
get {
parameters('color, 'bgColor) {
(color, bgColor) =>
val properResponse = write(ProperResponse(OK.intValue, s"Your preference is color $color with background color $bgColor."))
complete(HttpResponse(OK, entity = HttpEntity(ContentTypes.`application/json`, properResponse)))
}
}
}

A regular test case for this route would look like

"return proper response for check route if all parameters are provided" in {
Get("/check?color=red&bgColor=white") ~> webServer.route ~> check {
responseAs[String] shouldEqual """{"code":200,"message":"Your preference is color red with background color white."}"""
}
}

But what if we want to test when the parameters are missing?

That test case will be

"return a missing query parameter rejection for check route when parameters are not supplied" in {
Get("/check") ~> webServer.route ~> check {
rejection shouldEqual MissingQueryParamRejection("color")
}
}

Because we are passing no parameter, the route will certainly throw a rejection. And hence, we match the rejection that the route will throw with expected rejection. In the above case, MissingQueryParamRejection also expects a parameter (which is the first parameter that is missing), hence we match our rejection against MissingQueryParamRejection("color").

But as you must have noticed, our rejection handler gives a properly formatted response.
Testing response is equally important. It cannot be done like this,

"return a formatted response when a parameter rejection is encountered on check route" in {
Get("/check?color=red") ~> webServer.route ~> check {
responseAs[String] shouldEqual """{"code":400,"type":"Missing Parameter","message":"The required bgColor was not found."}"""
}
}

There is, however, a mechanism provided by Akka Http to test that even.
We do this by wrapping our route in akka.http.scaladsl.server.Route.seal. This is only needed in our test cases and not in the main code(but ensure that rejection handler is implicitly available in main code).
For writing the test case, we do need to bring our rejection handler in the scope of the test code which will look something like

implicit def rejectionHandler = webServer.rejectionHandler

And then, the test code will be -

"return a formatted response when a parameter rejection is encountered on check route" in {
Get("/check?color=red") ~> Route.seal(webServer.route) ~> check {
responseAs[String] shouldEqual """{"code":400,"type":"Missing Parameter","message":"The required bgColor was not found."}"""
}
}

Notice how the route has been wrapped inside Route.seal(). Doing it this way, allows us to check whether our rejection handler send the response the way we expected or not.

So eventually we have two ways to test our rejections:

  1. Matching expected rejections
  2. Using Route.seal()

So using these two ways, we can write our test cases for all kind of rejection handling that we may do in our code. You may find the entire code here.

Thank you for the read. Happy Coding :)

KNOLDUS-advt-sticker

--

--

Knoldus Inc.
Knoldus - Technical Insights

Group of smart Engineers with a Product mindset who partner with your business to drive competitive advantage | www.knoldus.com