Как исправить недостающее неявное значение параметра ta: TildeArrow в тестовой спецификации
Я работаю над простой тестовой спецификацией с использованием спрей, и я не могу заставить ее правильно компилироваться, не знаю, что я делаю что-то неправильно. Моя версия scala равна 2.9.3 и спрей 1.0.1 (Обновление любого из них не является подходящим вариантом). Здесь мой тестовый код:
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
Я получаю эту ошибку при запуске теста.
[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
Я пробовал разные решения, рассматриваемые по другим вопросам, и пока ничего не работает.
Spray.io: не удается скомпилировать тестовую спецификацию
как сделать скалярную работу с помощью распылителя и HttpServiceActor
Основное использование Spray-Testkit для проверки маршрута не работает
https://groups.google.com/forum/#!topic/spray-user/H5hkXuDGWYQ
https://groups.google.com/forum/#!topic/spray-user/zFUJSVBPM5c
ПРИМЕЧАНИЕ: Только для записи, я не использую scalatest или scalacheck. Является чисто испытанием маршрута [спрей]. И MyProxy расширяет актер
Ответы
Ответ 1
Я просто боролся с этой проблемой. Чтобы понять это, я пробежался по кодовой базе HTTP Akka, которая представляет собой джунгли implicit
s.
Моя проблема, казалось, TildeArrow
в том, что без правильного вторичного implicit
на месте правильный экземпляр TildeArrow
не был найден. Если вы посмотрите на код, экземпляр TildeArrow
, который требуется в сообщении об ошибке, определен как implicit def injectIntoRoute
в сопутствующем объекте, и для него требуется целый хост других implicit
s.
Я предлагаю выписать ваш код без каких-либо скрытых сахаров. Это должно помочь компилятору выдать правильное сообщение об ошибке:
"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'
})
}
}
Я думаю, что причина в том, что, поскольку нет конкретного экземпляра implicit
доступа, компилятор пытается удовлетворить неявное разрешение с помощью abstract class TildeArrow
, а у совершенно неопределенного абстрактного type
, ta.Out
, не определено ~>
,
В моем конкретном случае мне не хватало неявного ExecutionContextExecutor
, что бы это ни значило.
ОБНОВИТЬ
На самом деле, я рассмотрел его дальше, и проблема заключалась в том, что у меня было implicit def ec: ExecutionContextExecutor
объявленное в моем признаке маршрута, но trait RouteTest
определяет его имя как executor
, и поэтому, когда я определил свое собственное для выполнения отсутствующего неявного, я закончил с двумя одинаковыми неявными.
Это симпатичный API, но неявная магия - выход из-под контроля, IMO, особенно учитывая, насколько загадочными являются сообщения об ошибках.
Ответ 2
ScalatestRouteTest уже предоставляет неявную ActorySystem. Удалите модификатор "неявного" из вашего метода actorRefFactory, и тест должен быть выполнен.
Spray.io: не удается скомпилировать тестовую спецификацию
Ответ 3
для akka http:
в моем случае, которые относятся к akka-http-microservice
- модификатор
implicit
executionContext
, а также его необходимо удалить
- и должен изменить порядок следования следующим образом:
class ServiceSpec extends FlatSpec with Matchers with Service with ScalatestRouteTest
Ответ 4
В моем случае не найденная неявная ошибка появилась, когда в моем TestCase я также импортировал import monix.execution.Scheduler.Implicits.global
(который, вероятно, имеет какой-то тип ExecutionContext
).
Я исправил это, добавив импорт планировщика моникса только в том методе, где он мне был нужен, а не в верхнем импорте.
Ответ 5
Я могу воспроизвести то же сообщение об ошибке с Scala 2.10, если myRoutes
на самом деле не маршрут, а Directive[HNil]
.
Поэтому я предполагаю, что в вашем неподтвержденном классе service.MyProxy ваш маршрут не завершен.
т
trait MyProxy extends HttpService {
val myRoutes = path("foo")
}
Дает эту ошибку
trait MyProxy extends HttpService {
val myRoutes = path("foo") {
complete(StatusCodes.Accepted)
}
}
Нет.
Ответ 6
ваш build.sbt должен иметь зависимости для теста akka-stream вместе с тестом akka.
тогда он должен получить все зависимости.
обратитесь к этому документу: -
тестовый документ по маршруту Scala