尽管导入,但无法在测试中找到参数化类型自定义类的JSONReader

时间:2015-10-31 12:01:32

标签: scala spray scalatest spray-json

我有一个自定义类,如下所示

object SafeList {
  def apply[A](x: List[A]): SafeList[A] = if (x == null) EmptyList else HasItems[A](x)
}

sealed abstract class SafeList[+A] extends Product with Serializable {
  def get: List[A]
}

final case class HasItems[+A](x: List[A]) extends SafeList[A] {
  def get = x
}

case object EmptyList extends SafeList[Nothing] {
  def get = Nil
}

SafeList的格式化程序,看起来像这样

...
import spray.json.DefaultJsonProtocol._

trait SafeCollectionFormats {
  implicit def safeListFormat[A: RootJsonFormat] = new RootJsonFormat[SafeList[A]] {

    def read(json: JsValue): SafeList[A] = {
      val list: List[A] = listFormat[A].read(json)
      SafeList[A](list)
    }

    def write(sl: SafeList[A]): JsValue =
      listFormat[A].write(sl.get)
  }
}
object SafeCollectionFormats extends SafeCollectionFormats

然后编译。

但是当我为格式化程序添加测试时,就像这样......

...
import spray.json.DefaultJsonProtocol._
import marshalling.SafeCollectionFormats._
...

  "Unmarshalling a json array with items" should "produce a SafeList with items" in {
    val json: JsValue = JsArray(JsString("a"), JsString("b"), JsString("c"))
    val list = List("a", "b", "c")

    val result = json.convertTo[SafeList[String]]

    assertResult(list)(result)
  }

...

我收到以下编译错误

Error:(14, 32) Cannot find JsonReader or JsonFormat type class for myapp.types.SafeList[String]
    val result = json.convertTo[SafeList[String]]
                               ^

认为 this可能会有一些答案可以帮助我,但对我来说有点先进。我认为我的隐式safeListFormat 我的SafeList的JsonReader,并且我将它导入我的Spec。我不知道参数化类型是否令人困惑?

任何想法我做错了什么?

编辑:虽然我目前的测试是创建一个字符串的安全列表,但最终目的是创建一个我的域对象的安全列表。我将需要添加第二个构建MyObjects的JsArray的测试。所以A - 的类型在JSON术语中会有所不同。我的SafeList需要处理像字符串这样的简单对象和域对象。我想我可能会提出这个问题作为第二个问题,但我在这里提到了背景

1 个答案:

答案 0 :(得分:0)

只需做一点改动就可以解决这个问题:我SafeCollectionFormats延长了DefaultJsonProtocol

我还必须将safeListFormat的上下文界限更改为[A: JsonFormat]

trait SafeCollectionFormats extends DefaultJsonProtocol {
  implicit def safeListFormat[A: JsonFormat] = new RootJsonFormat[SafeList[A]] {

    def read(json: JsValue): SafeList[A] = {
      val list: List[A] = listFormat[A].read(json)
      SafeList[A](list)
    }

    def write(sl: SafeList[A]): JsValue =
      listFormat[A].write(sl.get)
  }
}

object SafeCollectionFormats extends SafeCollectionFormats

希望这会对你有所帮助。