Eu tenho um método privado na minha classe de teste que constrói um Bar
objeto comumente usado . O Bar
construtor chama o someMethod()
método no meu objeto zombado:
private @Mock Foo mockedObject; // My mocked object
...
private Bar getBar() {
Bar result = new Bar(mockedObject); // this calls mockedObject.someMethod()
}
Em alguns dos meus métodos de teste, eu quero verificar someMethod
também foi invocado por esse teste específico. Algo como o seguinte:
@Test
public void someTest() {
Bar bar = getBar();
// do some things
verify(mockedObject).someMethod(); // <--- will fail
}
Isso falha, porque o objeto simulado foi someMethod
chamado duas vezes. Eu não quero que meus métodos de teste se preocupem com os efeitos colaterais do meu getBar()
método, então seria razoável redefinir meu objeto simulado no final de getBar()
?
private Bar getBar() {
Bar result = new Bar(mockedObject); // this calls mockedObject.someMethod()
reset(mockedObject); // <-- is this OK?
}
Eu pergunto, porque a documentação sugere a redefinição de objetos simulados geralmente é indicativa de testes ruins. No entanto, isso parece bom para mim.
Alternativa
A escolha alternativa parece estar chamando:
verify(mockedObject, times(2)).someMethod();
o que, na minha opinião, força cada teste a conhecer as expectativas de getBar()
, sem nenhum ganho.
Mockito.clearInvocations(T... mocks)
Extraído dos documentos mockito .
Meu conselho é que você tente evitar o uso
reset()
. Na minha opinião, se você chamar duas vezes para someMethod, isso deve ser testado (talvez seja um acesso ao banco de dados ou outro processo longo que você queira cuidar).Se você realmente não se importa com isso, você pode usar:
Observe que esse último pode causar um resultado falso, se você chamar someMethod de getBar, e não depois (esse é um comportamento errado, mas o teste não falhará).
fonte
verify
meu método particular (o que eu concordo, provavelmente não pertence a ele). Congratulo-me com seus comentários sobre se sua resposta mudaria.Absolutamente não. Como costuma acontecer, a dificuldade que você está enfrentando para escrever um teste limpo é uma grande bandeira vermelha sobre o design do seu código de produção. Nesse caso, a melhor solução é refatorar seu código para que o construtor de Bar não chame nenhum método.
Construtores devem construir, não executar lógica. Pegue o valor de retorno do método e passe-o como um parâmetro construtor.
torna-se:
Se isso resultar na duplicação dessa lógica em muitos lugares, considere criar um método de fábrica que possa ser testado independentemente do seu objeto Bar:
Se essa refatoração for muito difícil, usar reset () é uma boa solução. Mas vamos deixar claro: isso indica que seu código foi mal projetado.
fonte