在测试 json api 时,测试返回的 json 是否与预期的一致。
使用了一个叫做 assert_json 的 GEM。但感觉过于繁琐,特别是在测试用例多的时候。
手写了几个 helper
def response_json
JSON.parse(response.body)
end
# data_map could look like {uid: :id,last_name: :last_name,full_name: '"#{exp['last_name']}#{exp['first_name']}"'}
def assert_json_equal(exp, data_map=nil, act=response_json)
act=JSON.parse(act) if act.is_a?(String)
data_map || (data_map=act.keys)
(data_map = Hash[data_map.map { |v| [v, v.to_sym] }]) if data_map.is_a?(Array) # convert array to hash (key == value)
data_map.each do |k, v|
k=k.to_s
if v.is_a?(Symbol)
assert_equal exp[v], act[k]
elsif v.is_a?(String)
assert_equal eval(v), act[k]
elsif v.is_a?(Hash) # support insets
assert_json_equal(exp,v,act[k])
else
false
end
end
end
假设我们有这样 1 个 model
User (id,last_name,first_name,password,updated_at,created_at)
当 json 返回值为 User.first.to_json 时,直接使用 assert_json_equal User.first 即可,而无需指定 data_map。
当 json 只返回 {"id":1,"last_name":'Jobs'} 时,则需使用数组作为 data_map,形如 assert_json_equal User.first,[:id,:last_name]
而当 json 返回的数据结果较复杂时,则需要使用 hash 作为 data_map,形如:
// json 返回结果
{"uid":1,full_name: 'Steve Jobs',password:'123'}
# 验证json返回
@data_map={
uid: :id,
full_name: '"#{exp.first_name} #{exp.last_name}"',
password: :password
}
assert_json_equal User.first,@data_map
总觉得这样的实现似乎有点怪怪的,以及是否有更优雅的写法?
Ruby 新手一枚,还望各位大牛不吝赐教。