Как исправить недостающее неявное значение параметра 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, особенно учитывая, насколько загадочными являются сообщения об ошибках.

Ответ 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