Pergunta

Eu sou novo para objetos fictícios, mas eu entendo que eu preciso ter minhas aulas implementar interfaces, a fim de zombar deles.

O problema que estou tendo é que na minha camada de acesso a dados, eu quero ter métodos estáticos, mas eu não posso colocar um método estático em uma interface.

Qual é a melhor maneira de contornar isso? Devo apenas usar métodos de instância (o que parece errado) ou há outra solução?

Foi útil?

Solução

Gostaria de usar um padrão método de objeto. Tenha uma instância estática desta, e chamá-lo no método estático. Deve ser possível a subclasse para testar, dependendo da sua plataforma de simulacros.

i. em sua classe com o método estático ter:

private static final MethodObject methodObject = new MethodObject();

public static void doSomething(){
    methodObject.doSomething();
}

e seu método de objeto pode ser uma forma muito simples, facilmente testado:

public class MethodObject {
    public void doSomething() {
        // do your thang
    }
}

Outras dicas

Sim, você usa métodos de instância. Os métodos estáticos basicamente dizer: "Existe uma maneira de conseguir essa funcionalidade - não é polimórfico." Mocking depende de polimorfismo.

Agora, se seus métodos estáticos logicamente não se preocupam com o que aplicação você está usando, eles podem ser capazes de tomar as interfaces como parâmetros, ou talvez trabalho sem interagir com o estado em tudo - mas por outro lado você deve estar usando instâncias (e provavelmente a injeção de dependência ao fio tudo junto).

Eu encontrei um blog via google com alguns grandes exemplos de como fazer isso:

  1. classe Refactor a ser uma classe de exemplo e implementar uma interface.

    Você já disse que você não quer fazer isso.

  2. Use uma classe instância invólucro com os delegados para membros classes estáticas

    Fazendo isso você pode simular uma interface estática através de delegados.

  3. Use uma classe instância invólucro com os membros protegidas que chamar a classe estática

    Este é provavelmente o mais fácil de simulação / gerenciar sem refatoração, pois ele pode apenas ser herdada de e ampliado.

Você pode estar tentando teste em muito profundo ponto de partida. Um teste não precisa ser criado para testar cada método individualmente; métodos privados e estáticos devem ser testados, chamando os métodos públicos que, em seguida, chamar os privados e estáticos, por sua vez.

Então, digamos que o seu código é assim:

public object GetData()
{
 object obj1 = GetDataFromWherever();
 object obj2 = TransformData(obj1);
 return obj2;
} 
private static object TransformData(object obj)
{
//Do whatever
}

Você não precisa escrever um teste contra o método TransformData (e você não pode). Em vez escrever um teste para o método GetData que testa o trabalho feito em TransformData.

Utilize métodos de instância sempre que possível.

Uso public static Func [T, U] (referências função estáticos que podem ser substituídos por funções simulada) em que os métodos de instância não são possíveis.

Uma solução simples é permitir mudar a implementação da classe estática através de um setter:

class ClassWithStatics {

  private IClassWithStaticsImpl implementation = new DefaultClassWithStaticsImpl();

  // Should only be invoked for testing purposes
  public static void overrideImplementation(IClassWithStaticsImpl implementation) {
     ClassWithStatics.implementation = implementation;
  }

  public static Foo someMethod() {
    return implementation.someMethod();
  }

}

Assim, na configuração de seus testes, você chama overrideImplementation com alguma interface zombou. A vantagem é que você não precisa de clientes de mudança de sua classe estática. A desvantagem é que você provavelmente vai ter um pouco de código duplicado, porque você terá que repetir os métodos da classe estática e é a implementação. Mas algumas vezes os métodos estáticos pode usar uma interface ligther que fornecem funcionalidade base.

O problema que você tem é quando você está usando 3 código partido e é chamado de um dos seus métodos. O que acabamos fazendo é envolvê-lo em um objeto, e chamando passá-lo com inj dep, e depois o teste de unidade pode zombar 3ª método estático partido chamar o setter com ele.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top