Recentemente me mandaram a seguinte pergunta: "Qual a diferença entre stub e mock?"
Quando falamos sobre as estratégias utilizadas para testar um código possuímos os seguintes conceitos.
Fake
O Fake representa uma implementação real mas não necessariamente igual a que será utilizada em ambiente produtivo, como por exemplo um repositório persistido em memória;
Obs.: O Fake é uma técnica utilizada em casos de testes integrados, onde nós testamos mais de uma camada em um único cenário de testes.
Vejam o exemplo abaixo:
Estamos criando uma classe concreta chamada ProdutoRepositoryFake que efetivamente implementa a interface IProdutoRepository, porém de uma forma simplificada, e potencialmente diferente da que será publicada em produção.
Spy
Spies são utilizados em casos onde queremos validar o comportamento de um método e sua interação com suas dependências, neste caso as dependências não são modificadas;
Obs.: O Spy é uma técnica utilizada em casos de testes Integrados, onde nós testamos mais de uma camada em um único cenário de testes.
Vejam o exemplo abaixo:
Estamos aplicando um Spy no nosso ProdutoRepositoryFake (pois nesse código de exemplo é a unica classe concreta que deriva de IProdutoRepository que nós temos), este mesmo exemplo poderia ser aplicado com qualquer classe concreta.
Neste exemplo foi preciso usar a interface IProdutoRepository e a classe ProdutoRepositoryFake como base para isso (linha 4).
Por que o código da linha 3 não funciona? Não funciona porque os métodos em questão não possuem o modificador "virtual", ou seja, ele não pode ser sobrescrito.
Stub
Stub é uma implementação que nos permite fornecer respostas prontas, são utilizados para cenários onde queremos validar apenas o resultado;
Vejam o exemplo abaixo:
Estamos criando um stub de um IProdutoRepository onde sempre que o método Obter for chamado passando o parâmetro id igual a 1, ele deve retornar um Produto { Id = 1, Nome = "TECLADO" }
Obs.: Está sendo utilizado um framework para simplificar a implementação do Stub, em um cenário natural, seria necessário criar um ProdutoRepositoryStub que imlpementasse a interface IProdutoRepository, o que seria muito mais verboso.
Mock
Diferentemente do Stub, o mock possui a capacidade de validar o comportamento da implementação, validando por exemplo quantas vezes um determinado método foi chamado, quais foram os parâmetros passados dentre outras informações, ou seja, o mock possui a capacidade do Spy e do Stub juntas.
Vejam o exemplo abaixo:
Estamos criando uma instancia do IProdutoRepository utilizando um Mock, sendo assim nós conseguimos definir arbitrariamente o retorno para os métodos que esta interface possui.
Além disso nós conseguimos também validar posteriormente se um determinado método foi chamado, com quais parametros foi chamado e quantas vezes ele foi chamado.
Dummy
Um objeto dummy é um objeto que nós utilizamos apenas para viabilizar a execução do nosso código, mas que para o nosso teste ele não será utilizado em momento algum.
Vejam o exemplo abaixo:
Estamos criando um método auxiliar que produz um Produto válido. Para o escopo do nosso teste é irrelevante conhecer as características de um produto válido, os valores atribuídos nas propriedades deste objeto também são irrelevantes.
Imagine um cenário onde temos dezenas de testes que precisam receber um Produto válido, eis que uma nova regra de validação é criada.
Automaticamente TODOS os testes que dependem de um Produto válido começarão a falhar (o que é bom), se não fosse pelo Dummy seria necessário modificar todos os testes um a um.
Considerações Finais
Segue o repositório no GitHub com os exemplos utilizados link
É válido lembrar que para estes exemplos estou usando o Moq que reduz significantemente a complexidade de escrever um duble de código.
Agora, mesmo que você prefira continuar falando que vai mocar tudo, você entende e sabe a diferença de cada uma dessas técnicas.
Se você gostou aproveite para deixar o seu Like e me seguir aqui e nas outras redes link
Top comments (0)