No outro dia, eu estava lendo um pouco sobre o Teste de Unidade e vi alguns exemplos em que as pessoas criam uma interface de repositório (ie IExampleRepository
) e depois criam o repositório real ( public class ExampleRepository : IExampleRepository
) e um repositório a ser usado para o teste de unidade ( FakeExampleRepository : IExampleRepository
).
No IExampleRepository
eles estavam implementando os mesmos métodos como no ExampleRepository
, no entanto, com diferentes consultas Linq.
Qual é exatamente o objetivo aqui? Eu pensei que uma parte da unidade testando seu código é garantir que um método funcione corretamente? Mas quando eu uso duas consultas totalmente diferentes, uma para 'real' e outra no teste, qual o sentido do teste?
ExampleRepository
, é melhor usar uma simulação. A justificativa é que você não está testando o repositório da unidade, mas outra coisa.ExampleRepository
, use a coisa real. Se você estiver testando a unidadeRepositoryController
, deve usar apenas umFakeExampleRepository
que retorne valores pré-especificados. Dessa forma, se um bug aparecerExampleRepository
, apenas esse teste de unidade falhará -RepositoryController
os testes continuarão bem-sucedidos, então você sabe que não há um bug lá. Se o controlador utilizado o repositório real, eles dois estariam falhando e você não saberia se você tivesse um bug ou 2.Eu concordo com as duas respostas de jk. e Jan Hudec - eles fornecem informações realmente boas. Mas pensei em acrescentar um pouco.
Sua primeira pergunta ("Qual é exatamente o objetivo aqui?") É importante. No caso que você está descrevendo, o objetivo real é testar as classes que estão utilizando a
IExampleRepository
interface, não testando as implementações do repositório. Criar oFakeExampleRepository
permite testar essas classes de clientes sem se preocupar com os detalhes da classe de repositório real.Isso é especialmente verdadeiro se o objeto que você está tentando configurar dificultar o teste (por exemplo, acessa o sistema de arquivos, liga para um serviço da web ou conversa com um banco de dados). Usando interfaces (e outras técnicas), você mantém o acoplamento baixo. Portanto, a classe
X
precisa conhecer apenas a interface e os detalhes da implementação. O objetivo é garantir que a classeX
esteja fazendo a coisa certa.Mocking (ou stubbing, fingindo ... existem diferenças sutis) é uma ferramenta poderosa para testes de unidade e TDD. Mas pode ser difícil criar e manter manualmente essas implementações. Portanto, a maioria dos idiomas agora tem bibliotecas de simulação para ajudar. Como você está usando C #, eu recomendaria o Moq porque é simples e muito poderoso. Em seguida, você pode testar a interface sem acumular código extra para as implementações simuladas.
fonte
the real objective is to test the classes that are utilizing the IExampleRepository interface
isso não é estritamente verdade. O objetivo é testá-lo independentemente do IExampleRepository. 1 por recomendar uma boa estrutura de isolamento.IExampleRepository
porque a classe em teste está acoplada a essa interface. Mas é independente de quaisquer implementações da interface. Admito que minha explicação provavelmente poderia usar um pouco mais de delicadeza. :)Isolamento.
A idéia de uma unidade de teste para testar a menor unidade de código possível . Você faz isso isolando -o de todos os outros códigos de produção no teste.
Ao criar classes falsas, o único código de produção é a classe em teste.
Se você criar um repositório falso corretamente e o teste falhar, você saberá que o problema está no código em teste. Isso oferece o benefício do diagnóstico gratuitamente.
Dê uma olhada nas estruturas de isolamento (como o Moq, como sugerido por @Allan), para poder gerar essas falsificações rapidamente para configurar as condições de teste e usá-las para reivindicar.
fonte
Há três razões pelas quais você pode querer fornecer uma instância simulada ao teste de unidade:
fonte