我想比较我在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
进行匹配。如何从每个索引中访问密钥?
答案 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([])