2012-08-11 18 views
5

Soy nuevo en Ruby on Rails y estoy haciendo http://ruby.railstutorial.org en este momento.Cómo mantener las pruebas rspec DRY con muchos "have_link"

Por lo que entiendo, se supone que el lenguaje debe seguir estrictamente este estándar DRY, pero está tan HÚMEDO cuando se trata de desarrollo impulsado por prueba en este tutorial.

Por ejemplo

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

Aquí tenemos un montón de filas que casi parece el mismo.

I'we trató este

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 

Este código funciona, pero es feo y parece que es más filas.

Así que quiero saber si es una mejor manera de agregar una matriz al método have_link.


Ahora tengo una gran idea, pero no sé cómo hacer que funcione.

Esta es mi ayudante (que no se ve como lo hizo cuando creé esta pregunta. Se editó después de una respuesta de Michael 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 

y esto debería ser ahora mi prueba

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

Esto funciona, pero no es fácil de usar. Cuando ejecuto la prueba y tengo un enlace no existe en la página, me dice que no tengo estos enlaces. Pero podré hacer que el ayudante me diga qué enlace me falta. Este es mi código de error

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

Respuesta

4

Para definir la costumbre se puede leer adaptadores de this feature y algunos inspiration.

Y escribir algo así:

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

Pero la OMI, su primer intento es la mejor manera de escribir que: limpio y fácil de leer.

+0

Gracias por su ayuda! He editado mi pregunta después de su respuesta.Esto funciona con pequeñas ediciones, pero todavía no estoy donde estaré (esta es mi pregunta editada). – aross

+0

Fuera del tema: Si puede, corte, apúnteme en la dirección correcta de donde puedo encontrar más información sobre "hacer | nombre, opciones |", no entiendo dónde puedo usar variables de multiplicación en funciones foreach. (Realmente no sé en qué googlear así que solo una sugerencia lo hará) – aross

+0

Debe personalizar el mensaje de falla. Consulte "Encuadernadores personalizados" en [el documento] (http://rubydoc.info/gems/rspec-expectations/RSpec/Matchers). –

7

Puede escribir un marcador personalizado, pero creo que no es la idea de las pruebas y DRY.

En el código, el mantra DRY recomienda mantener todo el conocimiento de su software en un lugar único e inequívoco. Ese no es el objetivo de las especificaciones. El objetivo de las especificaciones es detectar la corrección de un software de una manera explícita y fácil de leer.

Repita

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

si mucho más legible y fácil de leer que declarar y matriz de [texto, url] y iterar sobre ellos, incluso dentro de una cierta clase de coincidencias de costumbre.

En prueba, usted debería preferir la legibilidad por encima de la concisión.

+0

Incluso si no es la manera correcta de hacer las cosas, creo que es una gran manera de aprender cosas. Soy nuevo en rails y ruby ​​y jugar con las clases y ampliarlas es para mí una forma de entenderlas más. Pero ** tendré ** presente su opinión. – aross

+0

En ese caso, la respuesta que Michaël Witrant le dio parece ser la mejor. Escribir coincidencias personalizadas es una de las mejores características de Rspec. –

Cuestiones relacionadas