Estou usando o Mockito em alguns testes.
Tenho as seguintes aulas:
class BaseService {
public void save() {...}
}
public Childservice extends BaseService {
public void save(){
//some code
super.save();
}
}
Eu quero zombar apenas da segunda chamada ( super.save
) de ChildService
. A primeira chamada deve chamar o método real. Existe uma maneira de fazer isso?
Respostas:
Não, o Mockito não suporta isso.
Pode não ser a resposta que você está procurando, mas o que você está vendo é um sintoma de não aplicação do princípio de design:
Se você extrair uma estratégia em vez de estender uma superclasse, o problema desaparecerá.
Se, no entanto, você não tem permissão para alterar o código, mas deve testá-lo de qualquer maneira, e dessa maneira estranha, ainda há esperança. Com algumas ferramentas AOP (por exemplo AspectJ), você pode entrelaçar o código no método da superclasse e evitar sua execução totalmente (eca). Isso não funciona se você estiver usando proxies, você deve usar a modificação de bytecode (ou entrelaçamento do tempo de carregamento ou entrelaçamento do tempo de compilação). Existem frameworks de mocking que suportam esse tipo de truque também, como PowerMock e PowerMockito.
Eu sugiro que você vá para a refatoração, mas se essa não for uma opção, você se divertirá seriamente hackeando.
fonte
//some codes
código em um método que pode ser testado separadamente.Se você realmente não tem escolha para refatorar, você pode simular / fazer stub de tudo na chamada do super método, por exemplo
fonte
BaseService
é abstrato, embora eu não veja por que isso seria relevante.super.validate()
?Considere refatorar o código do método ChildService.save () para um método diferente e teste esse novo método em vez de testar ChildService.save (), dessa forma você evitará chamadas desnecessárias para o método super.
Exemplo:
fonte
crie um método protegido por pacote (assume a classe de teste no mesmo pacote) na subclasse que chama o método da superclasse e, a seguir, chame esse método no método da subclasse substituído. você pode então definir expectativas sobre este método em seu teste através do uso do padrão espião. não bonito, mas certamente melhor do que ter que lidar com toda a configuração de expectativa para o super método em seu teste
fonte
Mesmo que eu concorde totalmente com a resposta do iwein (
), admito que às vezes a herança parece natural e não sinto quebrá-la ou refatorá-la apenas por causa de um teste de unidade.
Então, minha sugestão:
E então, no teste de unidade:
fonte
A razão é que sua classe base não é pública, então o Mockito não pode interceptá-la devido à visibilidade, se você alterar a classe base como pública, ou @Override na subclasse (como pública), então o Mockito pode simular isso corretamente.
fonte
Talvez a opção mais fácil se a herança fizer sentido é criar um novo método (pacote privado ??) para chamar o super (vamos chamá-lo de superFindall), espionar a instância real e, em seguida, simular o método superFindAll () da maneira que você deseja simular a classe pai um. Não é a solução perfeita em termos de cobertura e visibilidade, mas deve dar conta do recado e é fácil de aplicar.
fonte