2012-08-11 70 views
5

我是Ruby on Rails的新手,我現在在做​​。如何讓rspec測試幹掉很多「have_link」

從我所瞭解的語言應該嚴格遵循這個DRY標準,但在本教程中,當涉及到測試驅動的開發時,它是如此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 

此代碼的工作,但它看起來醜陋,它更行。

所以我想知道如果這是一個更好的方式添加一個數組has_link方法。


我現在有一個好主意,但我不知道如何使它工作。

這是我的助手(它看起來並不像它沒有當我創造了這個問題,這是從邁克爾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

要定義的匹配器可以讀取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 2012-08-12 11:00:56

+0

題外話:如果你能夠,削減你指向我在哪裏我可以找到更多關於「do | name,options |」的信息,我不明白我在哪裏可以使用乘法變量foreach功能。 (我不真的知道該怎麼回答,所以只是提示會做) – aross 2012-08-12 11:06:49

+0

您應該自定義失敗消息。請參閱[文檔](http://rubydoc.info/gems/rspec-expectations/RSpec/Matchers)中的「自定義匹配器」。 – 2012-08-12 11:14:16

7

你可以寫一個自定義的匹配器,但我認爲那不是測試和DRY的想法。

在代碼中,DRY口頭禪鼓勵您將軟件的每一個知識都保存在一個獨特而明確的地方。 這不是規格的目標。規範的目標是以一種明確而易於閱讀的方式來欺騙軟件的正確性。

重複

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

如果更易讀易比聲明和[文本,URL]數組來讀取和遍歷他們,甚至裏面的某種自定義的匹配的。

在測試中,你應該更喜歡簡潔性的可讀性。

+0

即使這不是正確的做事方式,我認爲這是學習事物的好方法。我是新來的Rails和紅寶石,玩類和擴展他們是我的一種方式來更多地理解他們。 但我**會保持你的思考。 – aross 2012-08-12 11:59:15

+0

在這種情況下,MichaëlWitrant給你的答案似乎是最好的方法。編寫自定義匹配器是Rspec的最佳功能之一。 – 2012-08-12 13:47:07