尽管导入,但无法在测试中找到参数化自定义 class 的 JSONReader
Unable to find JSONReader for parameterised-typed custom class in test, despite import
我有一个自定义class如下
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 需要处理像字符串这样的简单对象和领域对象。我想我可能会把它作为第二个 SO 问题提出,但我在这里提到它是为了上下文
它只需要一点点改动就对我有用:我 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
希望对您有所帮助。
我有一个自定义class如下
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 需要处理像字符串这样的简单对象和领域对象。我想我可能会把它作为第二个 SO 问题提出,但我在这里提到它是为了上下文
它只需要一点点改动就对我有用:我 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
希望对您有所帮助。