Akka Http Route Test: Request was neither completed nor rejected within 1 second

5.1k views Asked by At

I am trying to write a test case for my application with akka-http. One of the testcases is given below:

import akka.http.scaladsl.model.headers.RawHeader
import akka.http.scaladsl.testkit.{ ScalatestRouteTest}
import com.reactore.common.core.{CommonCoreSystem, CommonActors, BootedCommonCoreSystem}
import scala.concurrent.duration._
import com.reactore.common.feature.referencedata.{DepartmentRepository, DepartmentService, DepartmentController, DepartmentRest}
import org.scalatest.concurrent.AsyncAssertions
import org.scalatest.time.Span
import org.scalatest.{WordSpec, Matchers}
import akka.http.scaladsl.model.StatusCodes._
/**
 * Created by krishna on 18/6/15.
 */


class DepartmentITTest extends WordSpec with Matchers with ScalatestRouteTest with CommonCoreSystem with CommonActors {
//  override val departmentRouter = system.actorOf(Props(classOf[DepartmentService], DepartmentRepository), Constants.DEPARTMENT_ROUTER_NAME)
  val deptRoute = (new DepartmentRest(departmentRouter)(DepartmentController).deptRoutes)
  implicit val timeout = AsyncAssertions.timeout(Span.convertDurationToSpan(5.second))
  val departmentJson = """{"id":13,"name":"ENGP22","shortCode":"ENGP2","parentDepartmentId":null,"mineId":null,"photoName":null,"isRemoved":false,"isPendingForApproval":false,"createdBy":0,"createDate":"2015-03-09 00:00:00","modifiedBy":0,"modifiedDate":"2015-03-09 00:00:00"}"""
  val header = RawHeader("apiKey", "xxxxx")
  "Service" should  {
    "return department by id" in {
      Get("/departments/13").withHeaders(header) ~> deptRoute ~> check {
//        Thread.sleep(500)
        status shouldBe OK
        responseAs[String] shouldBe departmentJson
      }
    }
  }
}

When I run this, it works correctly sometimes, and sometimes I get the error as Request was neither completed nor rejected within 1 second. I added a Thread.sleep for making it work now. I know that is not the correct solution. Could anyone tell me how to make the test wait for more than 1 second?

3

There are 3 answers

1
practechal On BEST ANSWER

The following is working for me:

import akka.actor.ActorSystem
import scala.concurrent.duration._
import spray.testkit.ScalatestRouteTest

class RouteSpec extends ScalatestRouteTest {
  implicit def default(implicit system: ActorSystem) = RouteTestTimeout(2.second)
...
1
Rich On

You can use the "eventually" matcher in ScalaTest to wait for a condition to become true:

eventually { status shouldBe OK }

http://www.artima.com/docs-scalatest-2.0.M5/org/scalatest/concurrent/Eventually.html

That should suffice if the Thread.sleep you commented out above fixes things for you.

However, it looks to me like the actual error is that the timeout that the RouteTest trait is using is too short. The error message "Request was neither completed nor rejected within 1 second." comes from RouteTestResultComponent via akka.http.scaladsl.testkit.RouteTest.

I think that the Thread.sleep is a distraction. The default timeout for routing tests is 1 second; see akka.http.scaladsl.testkit.RouteTestTimeout.default. You provide a 5 second implicit timeout in your code, but I think it's of a different type. Try making a RouteTestTimeout implicitly available with a longer timeout.

0
Tony Z On

you can simply update the config to dilate the timeout

akka {
  test {
    # factor by which to scale timeouts during tests, e.g. to account for shared
    # build system load
    timefactor =  3.0
  }
}