RSpec中如何比较包含数组的哈希且忽略数组内部元素顺序?
问题根因
你遇到的报错是因为使用了eq匹配器执行断言:eq是严格值匹配,会把a_collection_containing_exactly这类RSpec组合匹配器直接当做普通对象做相等校验,不会执行匹配器内部的忽略顺序对比逻辑,只有match、include这类支持组合匹配嵌套的断言方法才能识别这类特殊匹配器。
可用解决方案
方案1:正确使用RSpec组合匹配器(推荐)
把断言方法从eq换成match,同时在预期值中嵌套a_collection_containing_exactly即可:
expected = { something: { foo: a_collection_containing_exactly( { bar: 'baz' }, { one: 'two' } ) } } # 用match而非eq触发组合匹配逻辑 expect(response.parsed_body).to match(expected)
注意需保证你的rspec-expectations版本在3.0及以上,才支持哈希内嵌套组合匹配器的特性。
方案2:排序后对比(通用无依赖)
如果不想依赖RSpec的特殊匹配器,也可以将两个数组的元素做统一排序后再做相等校验,完全忽略原始顺序影响:
# 取出实际返回的foo数组 actual_foo = response.parsed_body[:something][:foo] # 预期的foo数组 expected_foo = [{ bar: 'baz' }, { one: 'two' }] # 将元素统一序列化后排序对比,适用于任意结构的数组元素 expect(actual_foo.map(&:to_s).sort).to eq(expected_foo.map(&:to_s).sort) # 如果元素结构固定,也可以按指定字段排序,对比结果更严谨 # expect(actual_foo.sort_by { |h| h.keys.first }).to eq(expected_foo.sort_by { |h| h.keys.first })
内容的提问来源于stack exchange,提问作者J.Krzus
相关产品推荐
相关产品推荐

