找不到类型为^的证据参数的隐含值 [英] could not find implicit value for evidence parameter of type ^

查看:89
本文介绍了找不到类型为^的证据参数的隐含值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为发布请求编写测试

I am trying to write a test for a Post request

这是我的代码:

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)
                   ^

这是什么意思?

我该如何解决?

这是正文中的json:

this is the json in the body :

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

这是代码中的对象:

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

推荐答案

您正在尝试调用以implicit Marshaller为参数的Post方法.请注意,只要编译器可以在范围内找到隐式参数,就不必提供隐式参数(请检查此内容以获取有关隐式的更多信息:

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?)

但是,您的代码没有定义任何隐式的Marshaller,因此编译器不知道如何将case class转换为HttpEntity.

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.

在您的情况下,您希望将其与Content-Type: application/json一起转换为HttpEntity.为此,您只需要定义:implicit val CreateLinkRequestMarshaller: Marshaller[CreateLinkRequest].这告诉scala如何将case class转换为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.

您还希望将其作为JSON传递到上下文,因此我们将定义JsonProtocol,即MyJsonProtocol.

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
}

请注意,您可以在其他地方定义这些隐式内容,例如package,然后将其导入测试类中.这样会更好,因为您肯定会想重用Marshaller.

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.

这篇关于找不到类型为^的证据参数的隐含值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆