Como testar o conteúdo de uma exceção com o RSpec

Dicas - 05/Out/2020 - por Luis Arantes

Exceções em Ruby costumam ser classes bem simples. Utilizamos muitas das classes de exceções já existentes na linguagem quando desejamos testar um funcionamento mais técnico do sistema e criamos nossas próprias classes de exceções para representar com mais precisão o que ocorre na lógica de negócio.

Geralmente estas classes seguem o padrão de apenas possuir um nome e uma mensagem customizados - se tornando classes "vazias", sem conteúdo adicional. Porém, pode acontecer de precisarmos repassar algum dado adicional em conjunto com a mensagem de erro, que poderá ser utilizado por outra classe preparada para resgatar a exceção. Exceções também são objetos, então podemos simplesmente encapsular atributos adicionais no objeto de exceção, além da mensagem de erro, se considerarmos viável.

Quando escrevemos um teste com o RSpec para esperar o lançamento de uma exceção, nós temos que encapsular o código que causa a exceção dentro de um bloco.

expect do
  starship.shoot
end.to raise_error(CannonDisabledError)

Com este formato também conseguimos validar facilmente o conteúdo da mensagem da exceção.

expect do
  starship.shoot
end.to raise_error(CannonDisabledError, 'Cannon was disabled due to low energy.')

No entanto, somente com esta declaração, não conseguimos verificar os conteúdos adicionais que a exceção pode conter. Para fazer isso é necessário inserir outro bloco no final da expectativa, que serve para avaliar o objeto da exceção que foi lançada.

expect do
  starship.shoot
end.to raise_error(CannonDisabledError) do |error|
  # a partir daqui avaliamos o objeto da exceção
  expect(error.remaining_ammo).to eq(10)
  expect(error.damaged?).to eq(false)
end

Referências e conteúdos adicionais

Foto de perfil do autor
Luis Arantes

Dev na Rebase

Desenvolvedor Ruby que gosta de falar sobre código, videogames e bandas de heavy metal obscuras