2012-08-11 44 views
5

मैं रेल पर रूबी के लिए नया हूं और मैं अभी http://ruby.railstutorial.org कर रहा हूं।rspec परीक्षणों को कैसे रखें "have_link" के साथ DRY

जो मैं समझता हूं कि भाषा को इस DRY मानक wery का सख्ती से पालन करना है, लेकिन यह इस ट्यूटोरियल में परीक्षण संचालित विकास की बात करते समय WET है।

उदाहरण

it { should have_link('Users', href: users_path) } 
it { should have_link('Profile', href: user_path(user)) } 
it { should have_link('Settings', href: edit_user_path(user)) } 
it { should have_link('Sign out', href: signout_path) } 

के लिए यहाँ हम पंक्तियों को लगभग एक ही लग रहा है की बहुत सारी है।

I'we की कोशिश की इस

it "should have following links from this array" do 
    [ 
     ['Users', href: users_path], 
     ['Profile', href: user_path(user)], 
     ['Settings', href: edit_user_path(user)], 
     ['Sign out', href: signout_path] 
    ].each { |a| page.should have_link(a[0], a[1]) } 
end 

इस कोड काम करता है लेकिन यह बदसूरत लग रहा है और यह अधिक पंक्तियाँ है।

तो मैं जानना चाहता हूं कि यह है_लिंक विधि में सरणी जोड़ने का एक बेहतर तरीका है या नहीं।


अब मेरे पास एक अच्छा विचार है लेकिन मुझे नहीं पता कि इसे कैसे काम करना है।

यह मेरा सहायक है (यह नहीं दिखता है जैसे कि यह किया था जब मैं इस सवाल का निर्माण किया। यह माइकल Witrant से एक जवाब के बाद संपादित किया जाता है) है

RSpec::Matchers.define :have_these_links do |*links| 
    match do |actual| 
     links.each do |link| 
      have_link(link.first, link.extract_options!).matches?(actual) 
     end 
    end 
end 

और यह अब अपने परीक्षण किया जाना चाहिए

it { should have_these_links(['Users', href: users_path], 
         ['Profile', href: user_path(user)], 
         ['Settings', href: edit_user_path(user)], 
         ['Sign out', href: signout_path]) } 

तो यह काम करता है लेकिन यह उपयोगकर्ता के अनुकूल नहीं है। जब मैं परीक्षण चलाता हूं और मेरे पास एक लिंक पृष्ठ पर मौजूद नहीं है तो यह मुझे बताता है कि मेरे पास ये लिंक नहीं हैं। लेकिन मैं सहायक को यह बता दूंगा कि मुझे कौन सा लिंक याद आ रहा है। यह कस्टम परिभाषित करने के लिए मेरी त्रुटि कोड

expected #<Capybara::Session> to have these links ["Users", {:href=>"/users"}], ["Test Link", {:href=>"/Does_not_exist"}], and ["Profile", {:href=>"https://stackoverflow.com/users/991"}] 
# ./spec/requests/authentication_pages_spec.rb:42:in `block (4 levels) in <top (required)>' 

उत्तर

4

है matchers आप this feature और कुछ inspiration पढ़ सकते हैं।

और लिखना कुछ है कि जैसे: स्वच्छ और पढ़ने में आसान:

RSpec::Matchers.define :have_links do |expected| 
    match do |actual| 
    expected.all? do |name, options| 
     have_link(name, options).matches?(actual) 
    end 
    end 
end 

लेकिन IMO, आपकी पहली कोशिश सबसे अच्छा तरीका यह लिखने के लिए है।

+0

आपकी मदद के लिए धन्यवाद! मैंने आपके उत्तर के बाद अपना प्रश्न संपादित कर लिया है।यह कुछ छोटे संपादनों को सफ़ेद करता है लेकिन मैं अभी भी नहीं हूं जहां मैं होगा (मेरे संपादित प्रश्न से)। – aross

+0

ऑफ-टॉपिक: यदि आप सक्षम हैं, तो आप मुझे सही तरीके से इंगित करते हैं कि मुझे "डू | नाम, विकल्प |" के बारे में अधिक जानकारी कहां मिल सकती है, मुझे समझ में नहीं आता कि मैं गुणा चर का उपयोग करने में सक्षम हूं foreach कार्यों। (मुझे सच में पता नहीं है कि Google पर क्या करना है, इसलिए सिर्फ एक संकेत होगा) – aross

+0

आपको विफलता संदेश को कस्टमाइज़ करना चाहिए। [डॉक्टर] (http://rubydoc.info/gems/rspec-expectations/RSpec/Matchers) में "कस्टम मैचर्स" देखें। –

7

आप एक कस्टम मैचर लिख सकते हैं, लेकिन मुझे लगता है कि यह परीक्षण और DRY का विचार नहीं है।

कोड में, DRY मंत्र आपके सॉफ़्टवेयर के ज्ञान के प्रत्येक टुकड़े को एक अद्वितीय और अस्पष्ट जगह में रखने के लिए प्रोत्साहित करता है। यह चश्मे का लक्ष्य नहीं है। चश्मा का लक्ष्य एक सॉफ्टवेयर की शुद्धता को स्पष्ट और आसान पढ़ने के तरीके में पछाड़ना है।

दोहराएँ

it { should have_link('Users', href: users_path) } 

अगर कहीं अधिक पठनीय और आसान घोषित करने और [पाठ, यूआरएल] की सरणी से पढ़ सकते हैं और उन पर पुनरावृति, यहां तक ​​कि कस्टम मिलान के कुछ प्रकार के अंदर करने के लिए।

परीक्षण में आपको संक्षेप में पठनीयता पसंद करना चाहिए।

+0

भले ही यह चीजों को करने का सही तरीका न हो, मुझे लगता है कि यह चीजों को सीखने का एक शानदार तरीका है। मैं रेल और रूबी के लिए नया हूं और कक्षाओं के साथ खेलना और उन्हें विस्तारित करना उनके लिए और अधिक समझने का एक तरीका है। लेकिन मैं ** ** आपके ऑप्टिऑन को दिमाग में रखूंगा। – aross

+0

उस मामले में माइकल विट्रंट ने जवाब दिया कि आपको सबसे अच्छा तरीका लगता है। लिखें कस्टम मैचर्स रुपयेपेक की सबसे अच्छी सुविधाओं में से एक है। –