hooks, pode ser que o seu teste tenha perdido a clareza.
Resumindo, antes de extrair tudo que for repetido entre os seus testes para before
hooks, pense se ao fazer isso você não está afetando a clareza do seu teste. Ou seja, não extraia tudo para before hooks só para deixar o código do seu teste DRY, pense
nas vantagens e desvantagens de fazer isso. Lembre-se que em código de teste, uma
das características mais importantes é a clareza e a possibilidade de entender fácil a relação de causa e consequência.
4.3
After hook
O after hook do RSpec serve para você executar código após os seus testes. Assim
como o before hook, ele te dá a opção de executar código depois de cada teste ou
depois de todos os seus testes:
67
4.3. After hook
Casa do Código
after(:each) do
# roda esse código uma vez depois de cada teste
end
# ou
# não precisa passar o :each, pois ele é a opção default do after
after do
# roda esse código uma vez depois de cada teste
end
after(:all) do
# roda esse código uma vez só depois de todos os testes
end
Um exemplo de onde pode ser útil o after hook é quando é necessário deletar
arquivos gerados durante os testes.
Imagine que você está escrevendo um teste de um objeto que salva um cache em
um arquivo no file system:
it "caches the result in a file" do
expect {
my_cool_object.run
}.to change { File.exists?(cache_path) }.from(false).to(true)
end
Ao rodar esse teste, um arquivo de cache é gerado. Para que seu teste não deixe
sujeira para trás, você pode usar o after hook para deletar esse arquivo gerado:
after(:all) do
FileUtils.rm(Dir.glob("#{cache_dir}/*"))
end
it "caches the result in a file" do
expect {
my_cool_object.run
}.to change { File.exists?(cache_path) }.from(false).to(true)
end
68
Casa do Código
Capítulo 4. Organização, refatoração e reuso de testes com o RSpec
4.4
Around hook
O around hook do RSpec é útil quando você precisa rodar código antes e depois do
seu teste:
describe "An around hook example" do
around do |example|
puts "Before the example"
example.run
puts "After the example"
end
it do
puts "Inside the example"
end
end
Podemos rodar o teste acima para entender o caminho da execução do teste
quando usamos um around hook :
Before the example
Inside the example
After the example
Vale a pena notar que o que fizemos acima poderia ter sido feito tranquilamente
usando before e after hooks:
describe "An around hook example" do
before do
puts "Before the example"
end
after do
puts "After the example"
end
it do
puts "Inside the example"
end
end
O lugar onde pode valer mais a pena usar o around hook ao invés de trocá-lo por
um before e um after é quando você tem alguma vantagem de rodar o seu teste dentro
69
4.5. Organizando seus testes
Casa do Código
de um bloco. Um exemplo disso é quando você quer rodar os seus testes dentro de
uma transação do seu banco de dados, de modo que você possa dar um revert de
todos os dados salvos no banco pelo seu teste simplesmente dando um rollback na
transação:
class Database
def self.transaction
puts "open transaction"
yield
puts "rollback transaction"
end
end
describe "around hook" do
around(:each) do |example|
Database.transaction(&example)
end
it "runs the example as a proc" do
puts "saving a lot of data in the database"
end
end
Ao executar o teste acima, podemos ver a seguinte saída:
open transaction
saving a lot of data in the database
rollback transaction
Repare que o método around passa como argumento para o seu bloco
o
example (teste criado pelo método
it), o qual você pode passar
como uma proc para um método que receba um bloco, como fizemos em
Database.transaction(&example).
4.5
Organizando seus testes
Organizar bem os seus testes é importante para a filosofia de testes como documen-
tação
do BDD. Dependendo de como seus testes estão organizados, pode ficar mais
difícil para o leitor entender os seus testes, prejudicando o entendimento da relação de causa e consequência. Como primeira dica para organizar seus testes, vamos dar
uma olhada nas quatro fases de um teste.
70
Casa do Código
Capítulo 4. Organização, refatoração e reuso de testes com o RSpec
Organizando seus testes segundo as quatro fases do xUnit
Um teste do padrão xUnit tem quatro fases, são elas:
1) setup: onde você coloca o SUT (system under test, por exemplo o objeto sendo testado) no estado necessário para o teste;
2) exercise: onde você interage com o SUT;
3) verify: onde você verifica o comportamento esperado;
4) teardown: onde você coloca o sistema no estado que ele estava antes do teste ser executado.
Talvez você não tenha percebido, mas todos os testes que escrevemos ao longo
desse livro até agora estão seguindo essas fases. Veja por exemplo o teste da pilha
que fizemos no capítulo 2:
describe Stack do
describe "#push" do
it "puts an element at the top of the stack" do
stack = Stack.new
stack.push(1)
stack.push(2)
expect(stack.top).to eq(2)
end
end
end
Leia o teste acima e tente identificar as 4 fases. Eu pessoalmente gosto de deixar