Conforme mencionado pela resposta mais votada, Martin Fowler discute essas distinções em Mocks Ar not Stubs e, em particular, no subtítulo The Difference Between Mocks and Stubs , portanto, leia esse artigo.
Em vez de focar em como essas coisas são diferentes, acho mais esclarecedor focar no motivo de esses serem conceitos distintos. Cada um existe para um propósito diferente.
Fakes
Um falso é uma implementação que se comporta "naturalmente", mas não é "real". Estes são conceitos difusos e, portanto, pessoas diferentes têm entendimentos diferentes sobre o que torna as coisas falsas.
Um exemplo de falsificação é um banco de dados na memória (por exemplo, usando o sqlite na :memory:
loja). Você nunca usaria isso para produção (já que os dados não são persistentes), mas é perfeitamente adequado como banco de dados para uso em um ambiente de teste. Também é muito mais leve que um banco de dados "real".
Como outro exemplo, talvez você use algum tipo de armazenamento de objetos (por exemplo, Amazon S3) na produção, mas em um teste você pode simplesmente salvar objetos em arquivos no disco; então sua implementação "salvar em disco" seria falsa. (Ou você pode até fingir a operação "salvar em disco" usando um sistema de arquivos na memória.)
Como terceiro exemplo, imagine um objeto que fornece uma API de cache; um objeto que implementa a interface correta, mas que simplesmente não executa armazenamento em cache, mas sempre retorna um erro de cache, seria uma espécie de falso.
O objetivo de uma falsificação não é afetar o comportamento do sistema em teste , mas sim simplificar a implementação do teste (removendo dependências desnecessárias ou pesadas).
Stubs
Um stub é uma implementação que se comporta "de maneira não natural". É pré-configurado (geralmente pela configuração do teste) para responder a entradas específicas com saídas específicas.
O objetivo de um stub é colocar seu sistema em teste em um estado específico. Por exemplo, se você estiver gravando um teste para algum código que interaja com uma API REST, poderá remover a API REST com uma API que sempre retorne uma resposta fixa ou que responda a uma solicitação de API com um erro específico. Dessa forma, você pode escrever testes que façam afirmações sobre como o sistema reage a esses estados; por exemplo, testando a resposta que seus usuários recebem se a API retornar um erro 404.
Um stub geralmente é implementado para responder apenas às interações exatas às quais você pediu. Mas o principal recurso que faz de algo um stub é seu objetivo : um stub é sobre como configurar seu caso de teste.
Zombaria
Um mock é semelhante a um stub, mas com a verificação adicionada. O objetivo de um mock é fazer afirmações sobre como o sistema em teste interagiu com a dependência .
Por exemplo, se você estiver escrevendo um teste para um sistema que carrega arquivos em um site, você pode criar uma simulação que aceita um arquivo e que pode ser usada para afirmar que o arquivo carregado estava correto. Ou, em uma escala menor, é comum usar uma simulação de um objeto para verificar se o sistema em teste chama métodos específicos do objeto simulado.
As simulações estão vinculadas ao teste de interação , que é uma metodologia de teste específica. As pessoas que preferem testar o estado do sistema em vez de interações com o sistema usarão zombarias com moderação, se houver.
Duplas de teste
Falsificações, stubs e zombarias pertencem à categoria de duplas de teste . Um teste duplo é qualquer objeto ou sistema que você usa em um teste, em vez de outra coisa. A maioria dos testes automatizados de software envolve o uso de testes duplos de algum tipo ou de outro. Alguns outros tipos de duplas de teste incluem valores fictícios , espiões , e I / O blackholes .