scala - ¿Cómo puedo corregir el valor implícito faltante para el parámetro ta: TildeArrow en una especificación de prueba?
routing spray (6)
Estoy trabajando en una especificación de prueba simple usando spray y no puedo compilarlo correctamente, no sé si estoy haciendo algo mal. Mi versión de scala es 2.9.3 y spray 1.0.1 (la actualización de cualquiera de ellos no es una opción adecuada). Aquí está el código de mi especificación de prueba:
import org.specs2.mutable.Specification
import spray.testkit.Specs2RouteTest
import spray.http._
import akka.util.Duration
import java.util.concurrent.TimeUnit
import service.MyProxy
abstract class MyTestSpec extends Specification with Specs2RouteTest with MyProxy{
val duration = Duration(30, TimeUnit.SECONDS)
implicit val routeTestTimeout = RouteTestTimeout(duration)
"MyProxy" should {
"return a json for GET requests to the /api/getclass/classCode path for a regular request" in {
Get("/api/getclass/123/") ~> myRoutes~> check {
responseAs[String] must contain("classCode")
contentType === ContentTypes.`application/json`
}
}
} // end should...
} //end class
Recibo este error cuando ejecuto la prueba.
[error] C:/Users/Desktop/Project/MyTestSpec.scala:23: could not find implicit value for parameter ta: MyProxySpec.this.TildeArrow[spray.routing.RequestContext,Unit]
[error] Get("/api/getclass/123/") ~> myRoutes~> check {
[error] ^
[error] one error found
[error] (test:compile) Compilation failed
He intentado diferentes soluciones vistas en otras preguntas y nada parece funcionar hasta ahora.
Spray.io: no se puede compilar espec. De prueba
Cómo hacer que Scalatest funcione con spraytestkit y HttpServiceActor
El uso básico de Spray-Testkit para probar una ruta no funciona
https://groups.google.com/forum/#!topic/spray-user/H5hkXuDGWYQ
https://groups.google.com/forum/#!topic/spray-user/zFUJSVBPM5c
NOTA: Solo para el registro, no estoy usando scalatest o scalacheck en esto. Es puramente una prueba de ruta [spray]. Y MyProxy extiende Actor
El ScalatestRouteTest ya proporciona un ActorySystem implícito. Elimine el modificador "implícito" de su método actorRefFactory y la prueba debería ejecutarse.
En mi caso, el error implícito no encontrado apareció cuando en mi TestCase también import monix.execution.Scheduler.Implicits.global
(que probablemente tenga algún tipo de ExecutionContext
).
Lo arreglé agregando la importación del planificador monix solo en el método donde lo necesitaba, no en las importaciones principales.
Puedo reproducir exactamente el mismo mensaje de error con Scala 2.10 si myRoutes
no es realmente una ruta sino una Directive[HNil]
.
Por lo tanto, estoy adivinando que en su servicio no mostrado. Clase de MyProxy su ruta no se completa.
es decir
trait MyProxy extends HttpService {
val myRoutes = path("foo")
}
Da este error
trait MyProxy extends HttpService {
val myRoutes = path("foo") {
complete(StatusCodes.Accepted)
}
}
No.
Solo luché con este problema. Para averiguarlo, vagué a través de la base de código HTTP de Akka , que es una jungla de s implicit
.
Mi problema parecía ser que, sin el derecho implicit
secundario, no se encontraba la instancia correcta de TildeArrow
. Si observa el código, la instancia de TildeArrow
, que se requiere en el mensaje de error, se define como una implicit def injectIntoRoute
en el objeto complementario y requiere una gran cantidad de otras s implicit
.
Sugiero escribir su código sin el azúcar implícita. Esto debería ayudar mejor al compilador a darte un mensaje de error adecuado:
"MyProxy" should {
"return a json for GET requests to the /api/getclass/classCode path for a regular request" in {
val request = Get("/api/getclass/123/")
val requestWithRoutes = request.~>(myRoutes)(TildeArrow.injectIntoRoute)
requestWithRoutes.~>(check {
responseAs[String] must contain("classCode")
contentType === ContentTypes.`application/json`
})
}
}
Creo que la razón es que, dado que no hay una instancia concreta de lo implicit
disponible, el compilador está tratando de satisfacer la resolución implícita con la abstract class TildeArrow
, y el type
abstracto completamente no especificado, ta.Out
, no tiene un ~>
definido .
En mi caso específico, me faltaba un ExecutionContextExecutor
implícito, sea lo que sea que eso signifique.
ACTUALIZAR
En realidad, lo examiné más a fondo y el problema era que tenía una implicit def ec: ExecutionContextExecutor
trait RouteTest
declarado en mi rasgo de ruta, pero el trait RouteTest
define su nombre como executor
, y cuando trait RouteTest
mío para cumplir con el implícito faltante, terminé arriba con dos de los mismos implícitos.
Es una API linda, pero la magia implícita está fuera de control, IMO, especialmente teniendo en cuenta lo crípticos que suelen ser los mensajes de error.
para akka http:
en mi caso que se refieren a akka-http-microservice
- El modificador
implicit
de laexecutionContext
y también debe eliminarse - y debe reordenar el rasgo así: la
class ServiceSpec extends FlatSpec with Matchers with Service with ScalatestRouteTest
su build.sbt debería tener dependencias para la prueba akka-stream junto con la prueba akka.
entonces debería obtener las dependencias que sean.
Consulte este documento: -