Scala SPECS2JSONMatchers:数组元素上的映射?
我使用SPECS2JSONMatcher来验证GET请求是否从其内部表示形式正确转换(在生成JSON之前,我们会进行一些操作)。我需要做的是,确保JSON数组中的元素与存储库中相应的对象匹配 我所尝试的:Scala SPECS2JSONMatchers:数组元素上的映射?,scala,specs2,Scala,Specs2,我使用SPECS2JSONMatcher来验证GET请求是否从其内部表示形式正确转换(在生成JSON之前,我们会进行一些操作)。我需要做的是,确保JSON数组中的元素与存储库中相应的对象匹配 我所尝试的: val response = response.entity.asString // Spray's way of getting the JSON response repository.all.map { obj => resp must */ ("id" -> obj.i
val response = response.entity.asString // Spray's way of getting the JSON response
repository.all.map { obj =>
resp must */ ("id" -> obj.id)
resp must */ ("state" -> generateState(obj)
}
问题是*/matcher只是发现“state”:“whater”(假设generateState返回“whater”)存在于JSON文档中的某个地方,而不一定存在于与ID匹配的同一个文档中
我尝试使用索引,但repository.all方法并不总是以相同的顺序返回元素,因此无法通过索引进行匹配
我想做的是,迭代JSON数组的元素并分别匹配每个元素。假设一个/##运算符(或其他什么)为每个元素使用匹配器:
resp /## { elem =>
val id = elem("id")
val obj = repository.lookup(id)
elem /("state" -> generateState(obj))
}
有人有办法做到这一点或类似的事情吗?现在最容易做的事情(直到对
JsonMatchers
进行严重重构)可能是在Matcher[String]
中执行一些解析并递归使用JsonMatchers
:
"""{'db' : { 'id' : '1', 'state' : 'ok_1'} }""" must /("db" -> stateIsOk)
// a string matcher for the json string in 'db'
def stateIsOk: Matcher[String] = { json: String =>
// you need to provide a way to access the 'id' field
// then you can go on using a json matcher for the state
findId(json) must beSome { id: String =>
val obj = repository.lookup(id)
json must /("state" -> generate(obj))
}
}
// I am using my own parse function here
def findId(json: String): Option[String] =
parse(json).flatMap { a =>
findDeep("id", a).collect { case JSONArray(List(v)) => v.toString }
}
// dummy system
def generate(id: String) = "ok_"+id
case object repository {
def lookup(id: String) = id
}
最后,我使用
responseAs[JArray]
、JArray\arr
和JObject#values
将JSON结构转换为List
s和Map
s,然后使用标准的List
和Map
匹配器。更加灵活