RSpec - Ganchos

Quando você está escrevendo testes de unidade, geralmente é conveniente executar o código de configuração e desmontagem antes e depois dos testes. O código de instalação é o código que configura ou “define” as condições para um teste. O código Teardown faz a limpeza, garante que o ambiente esteja em um estado consistente para os testes subsequentes.

De modo geral, seus testes devem ser independentes uns dos outros. Quando você executa um conjunto inteiro de testes e um deles falha, você deseja ter confiança de que ele falhou porque o código que está testando tem um bug, não porque o teste anterior deixou o ambiente em um estado inconsistente.

Os ganchos mais comuns usados ​​no RSpec são antes e depois dos ganchos. Eles fornecem uma maneira de definir e executar o código de configuração e desmontagem que discutimos acima. Vamos considerar este código de exemplo -

class SimpleClass 
   attr_accessor :message 
   
   def initialize() 
      puts "\nCreating a new instance of the SimpleClass class" 
      @message = 'howdy' 
   end 
   
   def update_message(new_message) 
      @message = new_message 
   end 
end 

describe SimpleClass do 
   before(:each) do 
      @simple_class = SimpleClass.new 
   end 
   
   it 'should have an initial message' do 
      expect(@simple_class).to_not be_nil
      @simple_class.message = 'Something else. . .' 
   end 
   
   it 'should be able to change its message' do
      @simple_class.update_message('a new message')
      expect(@simple_class.message).to_not be 'howdy' 
   end
end

Ao executar este código, você obterá a seguinte saída -

Creating a new instance of the SimpleClass class 
. 
Creating a new instance of the SimpleClass class 
. 
Finished in 0.003 seconds (files took 0.11401 seconds to load) 
2 examples, 0 failures

Vamos dar uma olhada mais de perto no que está acontecendo. O método before (: each) é onde definimos o código de configuração. Quando você passa o: each argumento, você está instruindo o método before a ser executado antes de cada exemplo em seu Grupo de Exemplo, ou seja, os dois blocos it dentro do bloco describe no código acima.

Na linha: @simple_class = SimpleClass.new, estamos criando uma nova instância da classe SimpleClass e atribuindo-a a uma variável de instância de um objeto. Que objeto você deve estar se perguntando? RSpec cria uma classe especial nos bastidores no escopo do bloco de descrição. Isso permite que você atribua valores a variáveis ​​de instância desta classe, que você pode acessar dentro dos blocos it em seus exemplos. Isso também torna mais fácil escrever um código mais limpo em nossos testes. Se cada teste (exemplo) precisa de uma instância de SimpleClass, podemos colocar esse código no gancho before e não ter que adicioná-lo a cada exemplo.

Observe que a linha “Criando uma nova instância da classe SimpleClass” é escrita no console duas vezes, isso mostra que, antes de o gancho ser chamado em cada um dos it blocks.

Como mencionamos, RSpec também tem um gancho posterior e ambos os ganchos antes e depois podem receber: tudo como um argumento. O gancho posterior será executado após o destino especificado. O destino: all significa que o gancho será executado antes / depois de todos os exemplos. Aqui está um exemplo simples que ilustra quando cada gancho é chamado.

describe "Before and after hooks" do 
   before(:each) do 
      puts "Runs before each Example" 
   end 
   
   after(:each) do 
      puts "Runs after each Example" 
   end 
   
   before(:all) do 
      puts "Runs before all Examples" 
   end 
   
   after(:all) do 
      puts "Runs after all Examples"
   end 
   
   it 'is the first Example in this spec file' do 
      puts 'Running the first Example' 
   end 
   
   it 'is the second Example in this spec file' do 
      puts 'Running the second Example' 
   end 
end

Ao executar o código acima, você verá esta saída -

Runs before all Examples 
Runs before each Example 
Running the first Example 
Runs after each Example 
.Runs before each Example 
Running the second Example 
Runs after each Example 
.Runs after all Examples