2016-03-07 113 views
7

我有兩個散列h1h2,我想在RSpec中進行比較。如何比較RSpec中的兩個哈希值?

我想檢查一下h1的元素是否與h2相同,然後進行一些轉換,我們將其稱爲f。也就是說,我想驗證h1h1[k] == f(h2[k])中的每個密鑰k

例如,如果在h2所有值的兩倍大的h1相應的值,然後我要檢查,對在H1每一個關鍵kh2[k] == h1[k] * 2

什麼是在RSpec中做到這一點的正確方法?目前我做:

h1 = ... 
expect(
    h2.all? { |k,v| 
    v == f(h1[k]) 
    } 
).to be true 

但這似乎笨重。

+0

我會創建一個輔助方法'equal?(other)'它可以進行計算 - 從這裏開始,'expect(h2.equal?(h1))。真實的' – onebree

+2

您的問題具有很高的誤導性。你在你的解釋和代碼中轉換了'h1'和'h2'的角色。 – sawa

+0

此外,您的描述(以及代碼)描述了匹配是一種方式,即,說明文本中的「h2」具有除「h1」以外的其他關鍵字並不重要。這是你的意圖嗎? – sawa

回答

4

聽起來像是你正在測試的是轉型。我會考慮寫這樣的:

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 

對我來說,描述清楚地說明了我們的期望。然後,我可以很容易地從測試中看到輸入和預期輸出。此外,該利用散列匹配,這將提供有關故障的兩個散列的一個很好的DIFF:

expected: {:k1=>2, :k2=>4} 
    got: {:k1=>1, :k2=>4} 

(compared using ==) 

Diff: 
@@ -1,3 +1,3 @@ 
-:k1 => 2, 
+:k1 => 1, 
:k2 => 4, 

雖然我會質疑鍵值關係意味着什麼。這些簡單的測試用例是否試圖通過?如果是這樣,我只是讓每一個獨特的測試。如果還有更多的東西,那麼我可能會質疑爲什麼變換方法沒有提供散列開始。

1
h1.each do |k, v| 
    expect(v).to eq(f(h2[k])) 
end 

至於我,它似乎更具可讀性。

0

對於一個確切的平等:

expect(h1).to eq h2.map { |k, v| [k, f(v)] }.to_h 
1

如何:

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 

多一點囉嗦,但也許更具可讀性?