将数组的数组与预定义的数组进行比较 - Ruby

时间:2015-03-20 13:14:53

标签: ruby arrays rspec cucumber

我想比较我在JSON响应中获得的所有结果与预先定义的键数组的比较。

所以我有这套钥匙

def key_array
 ["key1", "key2", "key3"] 
end

来自api调用的响应以@response

输出的格式(哈希数组)返回
{"0"=>
  {"key1"=>"value1",
   "key2"=>"value2",
   "key3"=>"value3"},
 "1"=>
   {"key1"=>"value1",
    "key2"=>"value2",
    "key3"=>"value3"},
 "2"=>
   {"key1"=>"value1",
    "key2"=>"value2",
    "key3"=>"value3"},
 "Status"=>"100"}
}

当我@response.keys时,我得到了

["0", "1", "2"]

我可以使用@response["0"].keys分别通过索引访问每组密钥,例如将返回

  ["key1", "key2", "key3"]

我想对rspec匹配器做的是检查api调用的每个返回结果是否都设置了key_array

中的键

目前

expect(@response.keys).to match_array(key_array)

将索引数组与我存储的key_array进行匹配。如何从每个索引中访问密钥?

4 个答案:

答案 0 :(得分:4)

@response.each_value do |value|
  expect(value.keys).to match_array(key_array)
end

这对你有用。

答案 1 :(得分:1)

required_keys = %w{key1 key2 key3}
@response.each do |key, hash|
  next if (key == "Status")
  expect(hash).to include(*required_keys)
end

您可以添加可选消息,以查看发生故障的索引:

@response.each do |key, hash|
  next if (key == "Status")
  expect(hash).to include(*required_keys), "Failed at #{key}"
end

next检查可以转换成正则表达式检查,以防您有其他想要忽略的非数字键,例如。

next if /\D/.match(key) # the \D matches non-digits

答案 2 :(得分:1)

如果你只需要一次调用期望方法,你可以

expect( @response.values.map{|h| h.keys.sort}.uniq ).to eq([%w(key1 key2 key3)])
然而,这是一种相当丑陋的方法

答案 3 :(得分:1)

我首先会收获不完整的东西:

incompletes = @response.reduce([]) { |memo, kv| 
  (key_array - kv.last.keys).empty? ? memo : memo << kv.first 
}

然后做检查:

expect(incompletes).to match_array([])

您是否只需要检查:

incompletes = @response.reject { |*kv| (key_array - kv.last.keys).empty? }
expect(incompletes).to match_array([]) 

这种前一种方法可以很容易地收集有关错误条目的任何所需信息,因为您可以自由地在结果数组中放置任何有价值的内容。希望它有所帮助。

UPD 状态为:

incompletes = @response.reject { |k,v| 
# ⇓⇓ is k integer? ⇓⇓  or  ⇓⇓ are valid keys all presented? ⇓⇓
   k.to_i.to_s != k    ||      (key_array - v.keys).empty? 
}
expect(incompletes).to match_array([])