seu argumento não é baseado no tipo desse objeto matcher, mas sim no seu compor-
tamento, ou seja, é baseado no famoso duck typing.
O protocolo mínimo de um matcher é que ele responda para o método
matches?(actual), onde actual é o objeto sendo testado. Conhecendo esse
protocolo, podemos escrever o matcher mais simples do mundo, que seria o seguinte:
class SimplestMatcher
def matches?(actual)
true
end
end
Para utilizar esse matcher, poderíamos escrever um teste do seguinte modo:
class SimplestMatcher
def matches?(actual)
true
end
end
describe 'The matcher procotol' do
context 'a minimal matcher' do
it 'has a #matches?(actual) method' do
expect('anything').to SimplestMatcher.new
end
end
end
54
Casa do Código
Capítulo 3. Introdução ao básico do RSpec
Talvez
você
estranhe
a
linha
expect('anything').to
SimplestMatcher.new devido ao argumento sendo passado para o mé-
todo to ser um objeto normal. Poderíamos deixar esse código um pouquinho
mais bonito construindo um helper method que retorne uma instância do nosso
matcher:
class SimplestMatcher
def matches?(actual)
true
end
end
describe 'The matcher procotol' do
it 'has a #matches?(actual) method' do
expect('anything').to simple_matcher
end
def simplest_matcher
SimplestMatcher.new
end
end
Essa idéia de ter um helper method que retorna uma instância do matcher que
você quer é exatamente o que o RSpec faz com praticamente todos os seus matchers.
Podemos ver isso examinando o código do RSpec para o eq matcher. Como vimos
antes, esse matcher é utilizado do seguinte modo:
actual
= 'got it'
expected = 'got it'
expect(actual).to eq(expected)
O que o RSpec faz por trás é que ele tem dentro do módulo RSpec::Matchers
um helper method chamado eq com o seguinte código:
def eq(expected)
BuiltIn::Eq.new(expected)
end
Como você pode ver, esse helper method retorna uma instância de um built-in
matcher do RSpec, o Eq Matcher. Esse matcher tem dentro dele uma implementa-
55
3.9. Pontos-chave deste capítulo
Casa do Código
ção do método matches?(actual), seguindo o protocolo de matchers, com um
código semelhante a este:
def matches?(actual)
actual == expected
end
Pronto, agora você já conhece o contrato básico entre uma expectation e um
matcher. Para um objeto ser um matcher, basta que ele responda para a mensagem
matches?(actual).
O último ponto para entender o contexto inteiro de uma expectation é saber para
que ela usa esse método matches?(actual). Internamente o método to chama
esse método, se ele retornar true é porque a expectation passou, se ele retornar
false, é porque ela quebrou. Simples assim.
A real importância de conhecer esse contrato é não para você construir seus pró-
prios matchers, isso você pode fazer usando a DSL do RSpec, pois ela automatiza um
monte de coisas para você. Conhecer esse contrato é importante para que uma ex-
pectation do RSpec pare de parecer mágica e faça sentido para você. Conhecer as
entranhas das suas ferramentas sempre é útil, e agora você já conhece um pouco
mais dos internals do RSpec. Como diz um grande amigo meu: não é feitiçaria, é
tecnologia!.
3.9
Pontos-chave deste capítulo
Neste capítulo nós conhecemos a estrutura básica de um teste com RSpec. Conhe-
cemos os métodos describe, it e a construção de uma expectation.
Aprendemos também que o RSpec tem muitos built-in matchers para nos pos-
sibilitar a escrever testes que pareçam com documentação, que estejam próximos do
semântica do domínio do problema sendo resolvido e para gerar mensagens de erro
claras.
Em seguida vimos como é simples escrever nosso próprio matcher usando a DSL
de custom matchers do RSpec. Dado que é muito fácil fazer isso, não exite em fazê-lo
quando o motivo for clareza do teste.
Por fim, vimos como o RSpec emprega duck typing no seu protocolo de matchers.
Agora, quando alguém vier com aquele velho papo de Ruby é magia negra, pelo
menos para os matchers do RSpec você já pode dizer que não é, e pode mostrar
como funciona por trás dos panos.
56
Casa do Código
Capítulo 3. Introdução ao básico do RSpec
Neste capítulo vimos todo o básico necessário para escrever testes com RSpec,
então já podemos ir para o próximo passo, que é como organizar, refatorar e reutilizar o código dos nossos testes. Pare um pouco para tomar um café, pois veremos tudo
só isso no próximo capítulo.
57
Capítulo 4
Organização, refatoração e reuso de
testes com o RSpec
Neste capítulo você irá aprender a como organizar seus testes. Irá aprender que um
teste de unidade tem uma narrativa e qual a vantagem de segui-la. Irá aprender tam-
bém a como refatorar seus testes para ficarem menos repetitivos, mas sem perder a
clareza dos mesmos.
Vamos lá!
4.1
Reduzindo duplicação com hooks do RSpec
O RSpec oferece três tipos de hooks para podermos reduzir a duplicação dos nossos
testes e rodarmos códigos arbitrários, antes, depois ou antes e depois dos nossos
testes, são eles: before hook, after hook e around hook. Vamos começar