Eu tenho uma classe com um método público Send()e alguns métodos privados. Ele chama alguns serviços da web e processa a resposta. O processamento é feito em métodos privados.
Quero testar o código da unidade. Meu entendimento é que os testes de unidade devem testar meu código isoladamente (ou seja, simular respostas do fornecedor).
Também acredito que métodos privados não precisam ser testados por unidade. Mas, se eu apenas testar o método Send (), meu código não será testado isoladamente e depende da ressonância do fornecedor.
Devo então tornar meus métodos privados públicos para que eu possa testá-los com respostas falsas? Parece uma prática ruim, já que só a turma precisa ligar para eles.
Desculpas, se é uma pergunta básica, sou bastante novo no teste de unidade.
Estou usando c # e VS2010
unit-testing dependencies
— Tom Squires
fonte
Se você não testar um método privado, como saber se funciona?
— Bryan Oakley
11
@BryanOakley, você não precisa saber que um método privado funciona, é privado. Você sabe que funciona porque os métodos públicos que a chamam passam em seus testes.
— StuperUser
@Bryan Oakley dê uma olhada no link
— Tom Squires
Olá Tom, Atualizei o link para torná-lo mais proeminente e fazer com que o texto do link reflita seu destino. Sinta-se à vontade para reverter.
— StuperUser
Respostas:
18
Você deve separar o código que lida com os serviços da web (isto é, enviar e receber dados) do código que processa os resultados. Mova o último código para uma classe distinta, tornando públicos os métodos necessários. Em seguida, você pode facilmente testar a lógica de processamento, isoladamente das dependências externas.
Com isso, você também torna seu código conforme o Princípio de responsabilidade única . Como regra geral, sentir a necessidade de testar métodos privados geralmente é uma indicação de que a classe tem muitas responsabilidades; portanto, deve ser refatorada em várias classes.
— Péter Török
fonte
3
Eu acho que um teste com essas dependências ( ligar para os fornecedores de serviços da Web ) é um teste de integração e não um teste de unidade.
— OC
fonte
3
Como outros já declararam, se os testes de unidade tiverem dependências externas, como serviços da Web ou chamadas ao banco de dados, NÃO serão testes de unidade, serão testes de integração.
Os verdadeiros testes de unidade podem ser executados independentemente dos componentes externos, além do componente que eles devem testar e devem ser repetidos independentemente do ambiente. Se os serviços da web externos forem desativados, seu teste de unidade não deve falhar.
Contornamos isso usando um Mocking Framework. Objetos simulados nos permitem criar uma simulação de um componente para que o componente em nosso teste de unidade use esses objetos simulados em vez de reais. Podemos injetar objetos simulados no componente testável e especificar quais argumentos estamos esperando, o que gostaríamos que retornasse quando for chamado, mesmo que exceção gostaríamos que fosse lançada. Eu recomendo ler mais sobre o assunto, pois melhorará a confiabilidade e a independência dos seus testes de unidade.
Para uma boa publicação sobre diferentes estruturas de simulação de C #, consulte o seguinte thread SO:
/programming/37359/what-c-mocking-framework-to-use
EDIT: Para os manifestamente sensíveis, devo admitir que esqueci de mencionar o DbUnit ou outras ferramentas transacionais que podem reverter alterações no banco de dados no final do teste. Eles também são repetíveis e podem ser independentes do ambiente com dados de teste gerados, portanto, um Mocking Framework não é necessário neste caso.
— maple_shaft
fonte
Alguém pode explicar o voto negativo? Eu não rasgar em PHP, ROR, bancos de dados NoSQL, Javascript no servidor, os produtos da Apple ou qualquer outra tendência fab mas eu ainda tenho um drive-by downvote de qualquer maneira: S
— maple_shaft
Eu acho que alguém não gostava de ter seus testes de unidade que está sendo chamado de "não testes de unidade em tudo" (não era eu) :)
— Daniel B
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.