2015-06-22 4 views
10

Sto provando a scrivere un test case per la mia applicazione con akka-http. Uno dei casi di test è il seguente:Akka Http Route Test: Richiesta non è stata né completata né respinta entro 1 secondo

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 
     } 
    } 
    } 
} 

Quando ho eseguito questo, funziona correttamente a volte, ea volte ho l'errore come Request was neither completed nor rejected within 1 second. Ho aggiunto un thread.sleep per farlo funzionare ora. So che non è la soluzione corretta. Qualcuno potrebbe dirmi come fare il test attendere più di 1 secondo?

risposta

5

Il seguente sta lavorando per 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) 
... 
+2

È sufficiente definire solo 'implicit val timeout = RouteTestTimeout (2.seconds)' –

6

È possibile utilizzare la "fine" matcher in ScalaTest ad aspettare una condizione di diventare vera:

eventually { status shouldBe OK } 

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

Questo dovrebbe essere sufficiente se il Thread.sleep si commentata correzioni sopra le cose per tu.

Tuttavia, mi sembra che l'errore effettivo sia che il timeout utilizzato dal tratto RouteTest sia troppo breve. Il messaggio di errore "Richiesta non è stata né completata né respinta entro 1 secondo." proviene da RouteTestResultComponent tramite akka.http.scaladsl.testkit.RouteTest.

Penso che il Thread.sleep sia una distrazione. Il timeout predefinito per i test di routing è 1 secondo; vedi akka.http.scaladsl.testkit.RouteTestTimeout.default. Fornisci un timeout implicito di 5 secondi nel codice, ma penso che sia di un tipo diverso. Prova a rendere implicitamente disponibile un RouteTestTimeout con un timeout più lungo.

+1

Ho messo questo nella mia classe spec e lo ha fatto modificare il timeout: 'privato implicit val timeout = RouteTestTimeout (intervallo di 10 secondi) '. – Lachlan

2

si può semplicemente aggiornare la configurazione per dilatare il timeout

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