如何保持rspec测试DRY有很多"have_link"

aro*_*oss 5 tdd rspec ruby-on-rails ruby-on-rails-3 railstutorial.org

我是Ruby on Rails的新手,我现在正在做http://ruby.railstutorial.org.

根据我的理解,该语言应该严格遵循这个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) }
Run Code Online (Sandbox Code Playgroud)

在这里,我们有很多行几乎看起来一样.

我试过这个

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
Run Code Online (Sandbox Code Playgroud)

这段代码有效,但它看起来很丑陋而且行数更多.

所以我想知道是否有更好的方法将数组添加到have_link方法.


我现在有一个好主意,但我不知道如何使它工作.

这是我的帮手(当我创建这个问题时看起来不像它.它是在MichaëlWitrant的答案之后编辑的)

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
Run Code Online (Sandbox Code Playgroud)

这应该是我的考验

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]) }
Run Code Online (Sandbox Code Playgroud)

所以这可行,但它不是用户友好的.当我运行测试并且页面上没有链接时,它告诉我我没有这些链接.但我可以让帮助者告诉我我错过了哪个链接.这是我的错误代码

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

mig*_*mba 7

你可以编写一个自定义匹配器,但我认为这不是测试和DRY的想法.

在代码中,DRY口头禅鼓励将软件的每一条知识都保存在一个独特而明确的地方.这不是规格的目标.规范的目标是以明确且易于阅读的方式提供软件的正确性.

重复

it { should have_link('Users', href: users_path) }
Run Code Online (Sandbox Code Playgroud)

如果比[text,url]的声明和数组更加可读和易读,甚至在某种自定义匹配器中迭代它们.

在测试中,您应该更喜欢可读性而不是简洁性.