Estou tentando testar uma classe que chama alguns serviços web do Hadoop. O código tem praticamente a forma:
method() {
...use Jersey client to create WebResource...
...make request...
...do something with response...
}
por exemplo, existe um método de criação de diretório, um método de criação de pasta etc.
Como o código está lidando com um serviço da Web externo sobre o qual eu não tenho controle, como posso fazer o teste unitário? Eu poderia tentar zombar do cliente / respostas do serviço web, mas isso quebra a diretriz que vi muito recentemente: "Não zombe de objetos que você não possui". Eu poderia configurar uma implementação fictícia de serviço da Web - isso ainda constituiria um "teste de unidade" ou seria um teste de integração? Simplesmente não é possível realizar testes de unidade nesse nível mais baixo - como um profissional de TDD faria isso?
fonte
Respostas:
Na minha opinião, você deve zombar das chamadas do serviço da web se for um teste de unidade, em oposição a um teste de integração.
Seu teste de unidade não deve testar se o serviço da web externo está funcionando ou se a sua integração com ele está correta. Sem ser muito dogmático sobre o TDD, observe que um efeito colateral de transformar seu teste de unidade em um teste de integração é que ele provavelmente será mais lento e você desejará testes de unidade rápidos .
Além disso, se o serviço da web estiver temporariamente fora do ar ou funcionando incorretamente, isso deve causar uma falha no seu teste de unidade? Não parece certo. Seu teste de unidade deve falhar por apenas um motivo: se houver um erro no código nessa "unidade".
A única parte do código relevante aqui é
...do something with response...
. Zombe do resto.fonte
Discordo de "não zombe de objetos que você não possui" quando estiver testando a unidade.
Zomba do propósito da existência é o fato de que haverá módulos, bibliotecas, classes que não possuiremos.
Minha sugestão para o seu cenário é simular a chamada de serviço da web.
Configure o mock de maneira que ele retorne dados ao seu módulo.
Certifique-se de cobrir todo o cenário, por exemplo, quando os dados retornados são nulos, quando os dados retornados são válidos etc.
E para o código que você possui, sua responsabilidade como desenvolvedor é garantir que o código que você está criando seja executado conforme o esperado em todos os cenários.
fonte
Eu usaria algo como EasyMock para este teste. As estruturas de zombaria são uma maneira ideal de remover dependências externas de uma classe e oferecem controle total sobre o resultado de dependências externas durante os testes. Para estender um pouco o seu exemplo:
A primeira coisa que você precisa fazer é extrair a lógica da sua classe em que você usa Jersey para obter um WebResource e chamar o serviço da Web em uma classe separada. A criação de uma interface para esta classe permitirá que você crie uma simulação para a qual você pode ditar o comportamento.
Depois que essa interface é criada, você pode criar uma simulação usando o EasyMock, que retornará um objeto especificado de acordo com o seu caso de teste. O exemplo acima é uma simplificação de como estruturar um teste simulado básico e como sua interface funcionará.
Para obter mais informações sobre estruturas de simulação, consulte esta pergunta . Além disso, este exemplo pressupõe o uso de Java, mas as estruturas de simulação estão disponíveis em todas as linguagens e, embora elas sejam implementadas de maneira diferente, elas geralmente funcionam da mesma maneira
fonte
Zombarias são aceitáveis neste caso, mas você não precisa. Em vez de teste de unidade
method()
, em vez disso, teste apenas a parte que lida com a resposta.Extraia uma função que
ResponseData
execute (de qualquer tipo que seja apropriado) e execute a ação.Em vez de zombar, agora você apenas constrói um objeto ResponseData e o passa.
Você pode deixar a chamada do serviço para testes completos de integração - que abrangerão
method()
no totalfonte
O que eu fiz e funciona:
3.1 Primeiro, todos os serviços da web são testados. De cada máquina, até as máquinas do desenvolvedor. Esses são os verdadeiros serviços da web, mas rodando em ambiente de desenvolvimento. Isso significa que os serviços da web nunca podem ser desativados ou responder a valores errados, porque, de outra forma, todo desenvolvedor reclama que não pode compilar.
3.2 Em seguida, todos os testes de unidade internos ao aplicativo são executados. Isso significa que todos os serviços da Web são ridicularizados e testados, executando os mesmos testes do 3.1 (e devem passar também; caso contrário, as zombarias estão erradas) e sendo invocados pelo aplicativo real como se estivessem realmente sendo usados. Se as zombarias estiverem erradas, você poderá executar o teste na versão 3.1 e registrar esses valores (solicitação, resposta) em um HashMap.
3.3 Em seguida, os mesmos testes do 3.2 são executados, mas desta vez contra os serviços da Web reais em execução no ambiente de desenvolvimento.
Depois que tudo isso foi concluído, para o ambiente de produção real, você só precisa fornecer o endereço real de cada serviço da web. Espero que isso não exija muita alteração na configuração.
fonte