Cómo crear nuestros propios “matchers” en RSpec
Dicen por ahí que uno no aprovecha RSpec al 100% hasta que no escribe sus propios matchers. Y la verdad, ahorran tiempo y hacen que nuestros tests sean mucho más legibles. No debemos olvidar que los tests son documentación. Lo mejor de todo es lo sencillos que son de crear.
Supongamos que a menudo comprobamos si un número es múltiplo de otro:
describe 9 do it "should be a multiple of 3" do (9 % 3).should == 0 endend
Feo, verdad? No es fácil interpretar a simple vista lo que queremos testear. Lo ideal sería poderlo expresar de la siguiente manera:
describe 9 do it "should be a multiple of 3" do 9.should be_a_multiple_of(3) endend
Manos a la obra. Creamos el fichero spec/support/matchers/be_a_multiple_of_matcher.rb con el siguiente contenido.
# spec/support/matchers/be_a_multiple_of_matcher.rb Spec::Matchers.define :be_a_multiple_of do |expected| match do |actual| actual % expected == 0 endend
Debemos asegurarnos de que el fichero es incluido en nuestros tests. Editamos spec/spec_helper.rb:
# spec/spec_helper.rb
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}...
Y con eso ya podemos usar el matcher be_a_multiple_of cuando queramos. Pero aún podemos hacerlo mejor. Si el test falla, el mensaje que veremos no hablará de múltiplos sino que simplemente dirá que esperábamos 0 y obtuvimos otra cosa.
Podemos hacer que los mensajes sean más descriptivos con lo siguiente:
# spec/support/matchers/be_a_multiple_of_matcher.rb
Spec::Matchers.define :be_a_multiple_of do |expected| match do |actual| actual % expected == 0 end
failure_message_for_should do |actual| "expected that #{actual} would be a precise multiple of #{expected}" end
failure_message_for_should_not do |actual| "expected that #{actual} would not be a precise multiple of #{expected}" end
description do "be a precise multiple of #{expected}" endend
Y con eso tenemos una herramienta más en nuestro repertorio para hacer las cosas más rápido y mejor. Para los interesados, el ejemplo original ha sido extraido de la Wiki de RSpec en GitHub.
English
Español