Classes de teste de unidade com funcionalidade online


23

Ao testar unidades de funções de uma classe que possui funções particulares que exigem funcionalidade online. Como alguém iria testá-lo?

Por exemplo:

public class Foo
{
    public int methodA()
    {
         int val = goOnlineToGetVal();

         return val;
    }

    private int goOnlineToGetVal()
    {
        CloudService c = new CloudService();
        int oval = c.getValueFromService();
        return oval;
    }
}

Se eu testasse a função: 'methodA ()', tentaria usar 'goOnlineToGetVal ()', que por sua vez tentaria ficar online, no entanto, se esse teste fosse feito sem funcionalidade. Como eu cobria cerca de 100% de cobertura da aula sem ficar on-line?


Seu método chama a API da nuvem ou também funciona?
Winston Ewert 15/09


4
Injeção de dependência ?
PhaDaPhunk 16/09

Respostas:


76

new CloudService()

E aí está o seu problema.

O design moderno do OO recomenda que esse tipo de dependência seja passado em vez de construído diretamente. Isso pode ser passado para a própria função ou para a classe no momento da construção. Também pode ser capturado ou agregado por um contêiner de Inversão de controle, se esse tipo de complexidade for justificado.

Nesse ponto, torna-se bastante trivial passar em um serviço falso / falso para fornecer seus dados "online" durante o teste. Melhor ainda, ele permite que seu software seja suficientemente flexível, para que você possa se adaptar rapidamente caso algum cliente (governamental?) Apareça e não queira usar a nuvem para seus valores. Ou você deseja despejar um provedor de nuvem para outro. Ou...


7
Eu acho que fiquei muito mais perto de entender o que diabos é a injeção de dependência.
marczellm

Onde é o melhor lugar para criar todas as instâncias que meu aplicativo precisa? O mais próximo possível do topo do meu aplicativo? Você só pode aplicar injeção de dependência até o momento; em algum momento, você precisará criar as instâncias por conta própria, em vez de passar como argumentos.
Paul

3
@ Paul - Depende. Na minha experiência, os aplicativos costumam parecer árvores binárias - uma classe / função / módulo une duas para fornecer um comportamento mais complexo. Uma dessas classes de "cola" é a que especifica a implementação concreta, que por sua vez é usada por algo acima que a cola com outra coisa, que por sua vez ... até chegar ao ponto de entrada que cola as peças grandes coerentemente. O "melhor" lugar é o lugar que permite que seu código faça o que precisa, sem fazê-lo ou saber sobre coisas que não deveria. Isso varia.
Telastyn 16/09/14

2
@Paul Normalmente, seu aplicativo é dividido entre uma "biblioteca", que é diretamente testada e deve usar esse tipo de injeção de dependência e código específico do aplicativo. O último geralmente se resume a alguma GUI, serviço da Web ou interface de linha de comando que chama diretamente a biblioteca com dados fornecidos pelo usuário. Essencialmente, o código específico do aplicativo criará as implementações concretas que a biblioteca injetada em dependência espera.
Darkhogg

@Paul Dê uma olhada em contêineres IoC como Castle Windsor, StructureMap, Ninject e Unity. Eles não são de forma a única maneira de fazer a injeção de dependência, mas eles podem ser muito informativo em termos de pensamento sobre a construção de um gráfico de objeto, de cima para baixo
Ben Aaronson

37

Eu implementaria assim:

public class Foo
{
    private ICloudService cloudService;

    public Foo(ICloudService s)
    {
       cloudService=s;
    }

    public int methodA()
    {
         int val = goOnlineToGetVal();

         return val;
    }

    private int goOnlineToGetVal()
    {
        int oval = cloudService.getValueFromService();
        return oval;
    }
}

A interface ICloudServicepode ser implementada com uma simulação para teste ou com o serviço de nuvem "real". Quando a instanciação new CloudService()é obrigatória para cada chamada de getValueFromService, ou CloudServiceé de uma API de terceiros que não pode ser alterada, implemente um wrapper, derivando ICloudServicee fazendo as chamadas apropriadas.


1
Este é definitivamente o caminho a seguir. Existem bibliotecas de classes que podem simular uma interface, fornecendo controle absoluto do teste.
22813 Greg Greghardhardt
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.