2012-08-11 35 views
5

Tôi mới sử dụng Ruby on Rails và tôi đang làm http://ruby.railstutorial.org ngay bây giờ.Cách giữ các kiểm tra rspec DRY với nhiều "have_link"

Từ những gì tôi hiểu ngôn ngữ được cho là tuân theo tiêu chuẩn DRY này một cách nghiêm túc nhưng nó rất WET khi nói đến việc phát triển thử nghiệm theo hướng dẫn trong hướng dẫn này.

Ví dụ

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) } 

Ở đây chúng ta có rất nhiều hàng mà hầu như trông giống nhau.

I'we cố gắng này

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 

Mã này hoạt động nhưng nó trông xấu xí và đó là nhiều hàng.

Vì vậy, tôi muốn biết nếu đó là cách tốt hơn để thêm mảng vào phương thức have_link.


Tôi hiện có ý tưởng tuyệt vời nhưng tôi không biết cách làm cho nó hoạt động.

Đây là helper của tôi (nó không giống như nó đã làm khi tôi tạo ra câu hỏi này. Nó được chỉnh sửa sau khi một câu trả lời từ Michaël 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 

và bây giờ điều này nên được thử nghiệm của tôi

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]) } 

Vì vậy, tính năng này hoạt động nhưng không thân thiện với người dùng. Khi tôi chạy thử nghiệm và tôi có một liên kết không tồn tại trên trang, nó cho tôi biết rằng tôi không có các liên kết này. Nhưng tôi sẽ có thể làm cho người trợ giúp cho tôi biết tôi đang thiếu liên kết nào. Đây là mã lỗi của tôi

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)>' 

Trả lời

4

Để xác định tùy chỉnh quẹt bạn có thể đọc this feature và một số inspiration.

Và viết một cái gì đó như thế:

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

Nhưng IMO, thử đầu tiên của bạn là cách tốt nhất để viết nó: sạch sẽ và dễ đọc.

+0

Cảm ơn sự giúp đỡ của bạn! Tôi đã chỉnh sửa câu hỏi của tôi sau câu trả lời của bạn.Điều này làm việc whit một số chỉnh sửa nhỏ nhưng im vẫn không phải nơi tôi sẽ được (se câu hỏi đã chỉnh sửa của tôi). – aross

+0

Off-Topic: Nếu bạn có thể, cắt bạn chỉ cho tôi trong direktion quyền nơi tôi có thể tìm thêm thông tin về "do | tên, tùy chọn |", Tôi không hiểu nơi tôi có thể sử dụng các biến nhân trên chức năng foreach. (Tôi không thực sự biết những gì để google trên chỉ là một gợi ý sẽ làm) – aross

+0

Bạn nên tùy chỉnh các thông báo lỗi. Xem "Đối sánh tùy chỉnh" trong [doc] (http://rubydoc.info/gems/rspec-expectations/RSpec/Matchers). –

7

Bạn có thể viết đối sánh tùy chỉnh, nhưng tôi nghĩ rằng đó không phải là ý tưởng thử nghiệm và DRY.

Trong mã, câu thần chú DRY khuyến khích giữ mọi phần kiến ​​thức về phần mềm của bạn ở một nơi độc đáo và rõ ràng. Đó không phải là mục tiêu của thông số kỹ thuật. Mục tiêu của các thông số kỹ thuật là để poof sự chính xác của một phần mềm một cách rõ ràng và dễ đọc.

Lặp lại

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

nếu xa hơn có thể đọc được và dễ đọc hơn tuyên bố và mảng [văn bản, url] và lặp qua chúng, thậm chí bên trong một số loại khớp tùy chỉnh.

Trong thử nghiệm, bạn nên thích khả năng đọc hơn sự đồng nhất.

+0

Thậm chí nếu đó không phải là cách đúng đắn để làm những điều tôi nghĩ đó là một cách tuyệt vời để học hỏi mọi thứ. Tôi mới đến đường ray và ruby ​​và để chơi với các lớp học và mở rộng chúng là cho tôi một cách để hiểu chúng hơn. Nhưng i ** sẽ ** lưu ý đến ý kiến ​​của bạn. – aross

+0

Trong trường hợp đó, câu trả lời mà Michaël Witrant đưa cho bạn có vẻ là cách tốt nhất. Viết đối sánh tùy chỉnh là một trong những tính năng tốt nhất của Rspec. –

Các vấn đề liên quan