Recentemente, observei que os Testes de integração são uma farsa de JB Rainsberger e agora estou procurando mais material sobre o assunto. Devo dizer que estou chocado com o quanto estamos fazendo de errado (por exemplo, teste de integração quando deveríamos testar a unidade), intrigado com os conceitos descritos por Rainsberger, mas também confuso sobre como aplicá-los. Gostaria de ter mais testes de colaboração e testes de contrato descritos , mas não sei por onde começar.
As únicas coisas que ficaram na minha cabeça são as 4 perguntas que os testes precisam fazer:
Lado a:
Do I ask the right question?
Can I deal with the answer?
Lado B:
Can I answer a question?
Do I answer correctly?
Mas como aplico isso a algum método aleatório na minha pilha de aplicativos?
Existe um livro, um tutorial ou um exemplo que dê um exemplo do mundo real e aplique essas idéias de microtestes isolados? Idealmente, o exemplo usa Java, Spring + PowerMock / Mockito / EasyMoock
Qualquer literatura que lide com esses conceitos em geral e me ajude a entendê-los melhor seria apreciada.
Além disso, se houver fóruns por aí, onde eu possa fazer perguntas mais detalhadas sobre como realizar testes de unidade corretamente e talvez até refatorar o código existente e publicar exemplos seria bom.
Obrigado!
Editar - algumas idéias adicionais:
Existe uma regra geral, quando usar uma simulação e quando um esboço para isolar uma classe em teste de seus colaboradores? Pode ser aplicado às 4 perguntas?
As melhores estruturas de zombaria parecem ser o PowerMock, permitindo-me definir precocemente para cada teste que classe eu quero zombar e o que ela deve retornar ou há algo melhor que você usou para fazer as perguntas acima? Existem bons tutoriais por aí que usam o PowerMock para aplicar alguns ou todos os princípios fornecidos a alguma parte de uma pilha de aplicativos do mundo real, como um DAO ou uma GUI?
Edição 2 - um exemplo
Apenas um exemplo do tipo de método que quero testar e meus pensamentos ..
Eu tenho um serviço web que salva pedidos. Nesse estágio, não estamos preocupados com a melhor segurança; portanto, para ter alguns, o serviço também precisará de um nome de usuário e senha para autenticar a solicitação de salvamento. Uma vez autenticado, o OrderManager
é chamado para salvar o arquivo Order
. Internamente, o gerente decide se é um novo pedido para que ele precise ser criado ou um existente que precise ser atualizado. (Isso não deve importar para o WebSerice, certo?)
@WebService
public class OrderService {
@Inject
private AuthenticationManager authenticationManager;
@Inject
private OrderManager orderManager;
public void save(String username, String password, Order order) {
authenticationManager.authenticate(username, password);
try {
orderManager.save(orde);
} finally {
authenticationManager.logout();
}
}
Agora estou me perguntando: o que exatamente estou testando aqui? Estou pensando que deve haver testes para êxito e falha na autenticação e para sucesso e falha na economia de pedidos.
Mas como posso dividir isso nas 4 perguntas? Minha turma em Teste é obviamente OrderService
(OS) e os colaboradores OrderManager
(OM) e AuthenticationManager
. (AM) Então, eu tenho os seguintes testes, por favor me corrija aqui, estou apenas pensando em voz alta:
OS <--> OM
- O SO solicita à OM que salve um pedido (que tipo de parâmetros diferentes eu testo aqui?
null
EOrder
? Importa se eleOrder
foi inicializado corretamente?) - OM responde a uma chamada de salvamento chamando algum outro método interno, teste II se esse método for chamado ?!
- O SO não deve falhar se o OM não falhar
- O SO deve falhar se OM falhar
... O quê mais?
E então, é claro, o SO <--> AM :
- O sistema operacional solicita que o AM seja autenticado - acho que testei como o AM reage a diferentes tipos de nome de usuário / senha?
- ...
Agora minha primeira conclusão :
Quanto ao WebSerice está em causa só pode testar 2 de 4 perguntas: A. Side Agora eu tenho que olhar para o OrderManager
e AuthenticationManager
e ver se eles podem responder as perguntas de lado B. Direito?
Em segundo lugar - acesso ao banco de dados:
A autenticação e a persistência de pedidos obviamente exigem alguns dados no banco de dados em um ambiente de produção. Para meus testes de unidade, no entanto, não precisarei deles, então zombarei das chamadas para retornar o resultado desejado, certo? Mas como eu zombei disso?
Eu preciso AuthenticationManager.authenticate
praticamente não fazer nada, pois, no caso de uma falha na autenticação, ele lançará um Exception
, caso contrário, ele terá o tipo de retorno void
. Como digo OrderService.save()
para usar meus mocked AuthenticationManager.authenticate()
?
E como configuro a AuthenticationManager
configuração para não fazer nada ou lançar uma exceção?
Posso dizer ao Spring para injetar um escárnio AuthenticationManager
que não fará nada / jogue um Exception
no meu OrderService
teste?