Automate Everything: Ruby, Linux and other hints, tips and tricks.

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.

You can follow any responses to this entry through the RSS 2.0 feed.