JSON तुलना समाधान
पैदावार एक साफ लेकिन संभावित रूप से बड़ी मुश्किल:
actual = JSON.parse(response.body, symbolize_names: true)
expected = { foo: "bar" }
expect(actual).to eq expected
वास्तविक डेटा से कंसोल आउटपुट का उदाहरण:
expected: {:story=>{:id=>1, :name=>"The Shire"}}
got: {:story=>{:id=>1, :name=>"The Shire", :description=>nil, :body=>nil, :number=>1}}
(compared using ==)
Diff:
@@ -1,2 +1,2 @@
-:story => {:id=>1, :name=>"The Shire"},
+:story => {:id=>1, :name=>"The Shire", :description=>nil, ...}
(@Floatingrock द्वारा टिप्पणी करने के लिए धन्यवाद)
स्ट्रिंग तुलना समाधान
यदि आप एक लौह-क्लैड समाधान चाहते हैं, तो आपको उन पार्सर का उपयोग करने से बचना चाहिए जो झूठी सकारात्मक समानता का परिचय दे सकते हैं; एक स्ट्रिंग के खिलाफ प्रतिक्रिया शरीर की तुलना करें। उदाहरण के लिए:
actual = response.body
expected = ({ foo: "bar" }).to_json
expect(actual).to eq expected
लेकिन यह दूसरा समाधान कम नेत्रहीन रूप से अनुकूल है क्योंकि यह क्रमबद्ध JSON का उपयोग करता है जिसमें बहुत सारे बच गए उद्धरण चिह्न शामिल होंगे।
कस्टम मिलान समाधान
मैं खुद को एक कस्टम मैचर लिखने की कोशिश करता हूं, जो जेन्सन पथ अलग हो सकता है, जो पुनरावर्ती स्लॉट पर बिल्कुल बेहतर काम करता है। निम्नलिखित को अपने rspec मैक्रो में जोड़ें:
def expect_response(actual, expected_status, expected_body = nil)
expect(response).to have_http_status(expected_status)
if expected_body
body = JSON.parse(actual.body, symbolize_names: true)
expect_json_eq(body, expected_body)
end
end
def expect_json_eq(actual, expected, path = "")
expect(actual.class).to eq(expected.class), "Type mismatch at path: #{path}"
if expected.class == Hash
expect(actual.keys).to match_array(expected.keys), "Keys mismatch at path: #{path}"
expected.keys.each do |key|
expect_json_eq(actual[key], expected[key], "#{path}/:#{key}")
end
elsif expected.class == Array
expected.each_with_index do |e, index|
expect_json_eq(actual[index], expected[index], "#{path}[#{index}]")
end
else
expect(actual).to eq(expected), "Type #{expected.class} expected #{expected.inspect} but got #{actual.inspect} at path: #{path}"
end
end
उपयोग 1 का उदाहरण:
expect_response(response, :no_content)
उपयोग 2 का उदाहरण:
expect_response(response, :ok, {
story: {
id: 1,
name: "Shire Burning",
revisions: [ ... ],
}
})
उदाहरण आउटपुट:
Type String expected "Shire Burning" but got "Shire Burnin" at path: /:story/:name
एक नेस्टेड सरणी में एक बेमेल गहरी प्रदर्शित करने के लिए एक और उदाहरण आउटपुट:
Type Integer expected 2 but got 1 at path: /:story/:revisions[0]/:version
जैसा कि आप देख सकते हैं, आउटपुट आपको बताता है कि आपके अपेक्षित JSON को ठीक करने के लिए कहां है।