Ruby 如何比较RSpec中的两个哈希?
我有两个散列Ruby 如何比较RSpec中的两个哈希?,ruby,rspec,Ruby,Rspec,我有两个散列h1和h2,我想在RSpec中进行比较 我想检查h1的元素在经过一些转换后是否与h2相同,我们称之为f。也就是说,我想验证对于h1中的每个键k,h1[k]==f(h2[k]) 例如,如果h2中的所有值是h1中相应值的两倍,那么我想检查h1中的每个键k,h2[k]==h1[k]*2 在RSpec中,正确的方法是什么?目前我有: h1 = ... expect( h2.all? { |k,v| v == f(h1[k]) } ).to be true 但这看起来很笨重
h1
和h2
,我想在RSpec中进行比较
我想检查h1
的元素在经过一些转换后是否与h2
相同,我们称之为f
。也就是说,我想验证对于h1
中的每个键k
,h1[k]==f(h2[k])
例如,如果h2
中的所有值是h1
中相应值的两倍,那么我想检查h1中的每个键k
,h2[k]==h1[k]*2
在RSpec中,正确的方法是什么?目前我有:
h1 = ...
expect(
h2.all? { |k,v|
v == f(h1[k])
}
).to be true
但这看起来很笨重
h1.each do |k, v|
expect(v).to eq(f(h2[k]))
end
对我来说,它似乎更具可读性。对于确切的等式:
expect(h1).to eq h2.map { |k, v| [k, f(v)] }.to_h
听起来您正在测试的是转换。我会考虑写这样的东西:
it "transforming something does something" do
base_data = { k1: 1, k2: 2 }
transformed_data = base_data.each_with_object({}) { |(k, v), t|
t[k] = f(v)
}
expect(transformed_data).to eq(
k1: 2,
k2: 4,
)
end
对我来说,描述清楚地说明了我们的期望。然后,我可以很容易地从测试中看出输入和预期输出是什么。此外,这还利用了哈希匹配器,它将在出现故障时提供两个哈希的良好差异:
expected: {:k1=>2, :k2=>4}
got: {:k1=>1, :k2=>4}
(compared using ==)
Diff:
@@ -1,3 +1,3 @@
-:k1 => 2,
+:k1 => 1,
:k2 => 4,
尽管我会质疑关键价值关系的含义。这些只是您试图运行的测试用例吗?如果是这样的话,我会让每一个测试都是独一无二的。如果还有其他问题,那么我可能会问,为什么转换方法没有提供散列作为开始。如何:
h2 = f(h1)
expect(h2.keys).to eq(h1.keys) # I assume you want this, too
h1.keys.each do |k|
expect(h2[k]).to eq(h1[k] * 2)
end
有点冗长,但可能更可读?如果有人来寻找大嵌套散列的更好的差异,我想到了这个:
RSpec::Matchers.define :be_a_hash_like do |expected_hash|
match do |actual_hash|
matching_results = actual_hash == expected_hash
unless matching_results
system(
"git diff $(echo '#{JSON.pretty_generate(expected_hash)}' | git hash-object -w --stdin) " +
"$(echo '#{JSON.pretty_generate(actual_hash)}' | git hash-object -w --stdin) --word-diff",
out: $stdout,
err: :out
)
end
matching_results
end
failure_message { 'Look at the Diff above! ^^^' }
end
# then use:
expect(actual).to be_a_hash_like(expected)
原意:
输出示例:
我们在RSPEC中用来处理这个问题
我们开发了一个定制匹配器:
RSpec::Matchers.define :match_hash do |expected|
match do |actual|
Hashdiff.best_diff(expected, actual).blank?
end
failure_message do |actual|
"expected that #{actual} would match #{expected}, but it has these differences: #{Hashdiff.best_diff(expected, actual)}"
end
end
我们是这样使用的:
expect(实际的\u散列)。为了匹配\u散列(expected\u散列)
我会创建一个助手方法equal?(其他)
来进行计算——从那里开始,expect(h2.equal?(h1))。如果是真的
你的问题是非常容易误导的。您正在切换解释和代码中的h1
和h2
角色。此外,您的描述(以及代码)说明匹配是单向的,即解释文本中的h2
是否有h1
以外的键并不重要。这是你想要的吗?