Ruby 如何检验一个 json/hash 与给定的 hash 结构是否相同 / 相似?

nagae_memooff · 2014年05月12日 · 最后由 nagae_memooff 回复于 2014年05月12日 · 2935 次阅读

情况是这样的,我最近试图对一些 API 做测试,测试的目的仅仅是模拟客户端的行为以及对接口的要求(比如要求什么样子的字段和结构),不考虑 API 的具体代码和复杂的逻辑检验。 其中有一个情况是,我想要测试其中部分 API 返回的 json 是否满足给定的结构,比如我期望某个 api 返回如下结构的 json:

{
  "status" : "OK",
  "msg" : [   
    {
      "id" : 15,
      "equipments" : [
        {
          "description": "desc_a",
          "equip_type" : "type_a",
          "id": 1
        },
        {
          "description": "desc_b",
          "equip_type" : "type_b",
          "id": 2
        },
        {
          "description": "desc_c",
          "equip_type" : "type_c",
          "id": 3
        }
      ]
    },
    {
      "id" : 17,
      "equipments" : [
        {
          "description": "desc_d",
          "equip_type" : "type_a",
          "id": 4
        },
        {
          "description": "desc_e",
          "equip_type" : "type_b",
          "id": 5
        },
        {
          "description": "desc_f",
          "equip_type" : "type_c",
          "id": 6
        }
      ]
    }
  ]
}

类似这种结构,同时又考虑到服务器端返回的数组可能为空数组,这种情况也认为结构符合要求。 对于这种类型的比较,在 rspec 或 ruby 中有没有现成的 gem 可以使用? 如果没有的话,自己比较需要解决两个问题: 1、如何描述期待的数据结构 2、如何将期待的结构与实际返回的做对比

曾经我是直接提取 key 然后比较是不是规定的 key 都存在。但是 hash 的层级没有你这么多。

#1 楼 @Shadow 我第一反应也想到这个办法,但是如果不判断层级关系的话这个检查就很难处理空数组的情况,判断层级关系的话又会比较复杂……我目前只能想到递归判断了

哪里有那么复杂,还需要递归

空数组这些问题都不存在,因为数据都是你自己临时创建的,回复必须符合要求。要测空数组就自己创建空数组。

let(:json){ JSON.parse(response.body)

describe "get expected response" do
  before do
    # Prepare data
    # Send request
  end

  it "returns status okay" do
    expect(json["status"].to eq("OK"
  end

  it "returns all msgs" do
    expect(json["msg"].size).to eq(2)
  end

  it "returns msgs with order" do
    expect(json["msg"][0].id).to eq(obj1.id)
  end

  it "returns msgs with equipment" do
    # 后面你就自己判断要不要继续测了。
  end
end

#3 楼 @billy 我的测试代码和系统是隔离开的,也就是说数据不是我在程序里造出来的,我也没有办法进入到服务器端代码的逻辑里,只能通过 HTTP 请求和返回的 json 来判断。

@nagae_memooff 你控制不了的东西是没法测的啊。返回什么是服务器的事情,你的客户端是管不了的。现在这个情况你只能 mock 一些 json,有空的,有满的,让你的客户端 Javascript 去测这些。

然后把这些 json 扔给后端的小伙伴说这就是我的需求。

#5 楼 @billy 其实我这个测试的目的仅仅是模拟客户端的行为以及对接口的要求(比如要求什么样子的字段和结构),对服务器端的接口做一个最基本的检测而已,并不追求覆盖面和严格的逻辑检验啦。

@nagae_memooff 那就肉测吧。测试都是测 output,没有测 input 的。

#8 楼 @billy 就是测 output 啊。测试的目的是尽量确保服务器端返回的 json 结构满足客户端的要求。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号