Matchers Customizados no RSpec

29 12 2010

Esses dias me deparei com um caso no qual havia uma ótima possibilidade de criar um matcher customizado.
Em uma verificação, precisei fazer algo do tipo:
my_contacts.should list_friends
Porém em outra, o seguinte:
my_contacts.should list_friends 5

Com base na documentação do RSpec, consegui fazer o seguinte:
Spec::Matchers.define :list_friends do |count|
match do |my_contacts|
if count
my_contacts.select{|contact| contact.is_friend?}.size == count
else
my_contacts.any?{|contact| contact.is_friend?}
end
end
failure_message_for_should do |contacts|
if count
"expected that #{count} of your contacts were your friends"
else
"expected that any of your contacts were your friend"
end
end
failure_message_for_should_not do |contacts|
if count
"didn't expected that #{count} of your contacts were your friends"
else
"expected that none of your contacts were your friend"
end
end
description do
"assure that you have any, many, or no friends"
end
end

Em uma aplicação rails, sugiro que salve o arquivo conforme o seguinte: spec/support/matchers/friends_matchers.rb

Solução limpa, bonita, que além de deixar seu teste mais elegante, auxiliará caso ocorra algum erro, especificando na própria mensagem o erro que ocorreu.