could not find implicit value for evidence parameter of type ^

为君一笑 提交于 2019-12-06 06:33:04

问题


I am trying to write a test for a Post request

here is my code :

val request = CreateLinkRequest(token = Some(validToken),billing_ref_id = Some("123"), store_id = Some("123"), agent_id = Some("123"))

val endPoint = Uri(this.serverRootUrl + "path").toString
val post = Post(endPoint, request)
val pipeline = jsonAsStringPipeline(post)
val responseContents = Await.ready(pipeline, atMost = callMaxWaitDuration)

But this doesnt compile, I keep getting this error :

Error:(156, 20) could not find implicit value for evidence parameter of type spray.httpx.marshalling.Marshaller[CreateLinkSpec.this.CreateLinkRequest]
    val post = Post(endPoint, request)
               ^
Error:(156, 20) not enough arguments for method apply: (implicit evidence$1: 

spray.httpx.marshalling.Marshaller[CreateLinkSpec.this.CreateLinkRequest])spray.http.HttpRequest in class RequestBuilder.
Unspecified value parameter evidence$1.
    val post = Post(endPoint, request)
                   ^

What does this mean?

How can I fix it ?

EDIT: this is the json in the body :

{ token:"123", billing_ref_id:"123", store_id:"123", agent_id:"123"}

and this is the object for it in the code:

private final case class CreateLinkRequest(
    token: Option[String] = Some(validToken),
    billing_ref_id: Option[String] = Some(Random.alphanumeric.take(10).mkString),
    agent_id: Option[String] = Some(Random.alphanumeric.take(3).mkString),
    store_id: Option[String] = Some(Random.alphanumeric.take(3).mkString)
    )

回答1:


You are trying to call Post method which takes implicit Marshaller as parameter. Note that implicit parameters don't have to be provided as long as the compiler can find one in the scope (check this for more info about implicits: Where does Scala look for implicits?)

However, your code doesn't have any implicit Marshaller defined so the compiler doesn't know how to convert your case class into the HttpEntity.

In your case you want it to be converted into the HttpEntity with Content-Type: application/json. To do that you just need to define: implicit val CreateLinkRequestMarshaller: Marshaller[CreateLinkRequest]. This tells scala how to convert your case class into the HttpEntity.

You also want it to be passed to the context as JSON, so we are going to define our JsonProtocol, i.e. MyJsonProtocol.

package test

import spray.http.HttpEntity
import spray.http._
import spray.json._
import spray.httpx.marshalling.{Marshaller, MarshallingContext}
import test.TestMarshaller.CreateLinkRequest


object MyJsonProtocol extends DefaultJsonProtocol {
  implicit def createLinkRequestFormat: JsonFormat[CreateLinkRequest] = jsonFormat4(CreateLinkRequest)
}

object TestMarshaller extends App {
  import MyJsonProtocol._

  case class CreateLinkRequest(token: Option[String], billing_ref_id: Option[String], store_id: Option[String], agent_id: Option[String])

  implicit val CreateLinkRequestMarshaller: Marshaller[CreateLinkRequest] = new Marshaller[CreateLinkRequest] {
    override def apply(value: CreateLinkRequest, ctx: MarshallingContext): Unit = {
      val entity = HttpEntity(MediaTypes.`application/json`, value.toJson.compactPrint)
      ctx.marshalTo(entity)
    }
  }

  // Here goes your test
}

Note that you can define these implicits somewhere else, e.g. a package and then just import it in the test class. This would be better because you will certainly want to reuse the Marshaller.



来源:https://stackoverflow.com/questions/41093083/could-not-find-implicit-value-for-evidence-parameter-of-type

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!