Use Mockito para verificar se nada é chamado após um método
-
21-08-2019 - |
Pergunta
Estou usando o Mockito para escrever um teste de unidade em Java, e gostaria de verificar se um determinado método é o último chamado em um objeto.
Estou fazendo algo assim no código em teste:
row.setSomething(value);
row.setSomethingElse(anotherValue);
row.editABunchMoreStuff();
row.saveToDatabase();
Na minha simulação, não me importo com a ordem em que edito tudo na fila, mas é muito importante que eu não Tente fazer algo mais depois de salvá -lo. Existe uma boa maneira de fazer isso?
Observe que não estou procurando verifyNomoreInterrações: ele não confirma que o SaveTodatabase é a última coisa chamada, e também falha se eu chamar alguma coisa na linha que não verifiquei explicitamente. Eu gostaria de poder dizer algo como:
verify(row).setSomething(value);
verify(row).setSomethingElse(anotherValue);
verifyTheLastThingCalledOn(row).saveToDatabase();
Se ajudar, estou mudando para o Mockito de um teste de jmock que fez isso:
row.expects(once()).method("saveToDatabase").id("save");
row.expects(never()).method(ANYTHING).after("save");
Solução
Eu acho que requer mais trabalho personalizado.
verify(row, new LastCall()).saveToDatabase();
e depois
public class LastCall implements VerificationMode {
public void verify(VerificationData data) {
List<Invocation> invocations = data.getAllInvocations();
InvocationMatcher matcher = data.getWanted();
Invocation invocation = invocations.get(invocations.size() - 1);
if (!matcher.matches(invocation)) throw new MockitoException("...");
}
}
Resposta anterior:
Você está certo. VerifyNomoreInterrações é o que você precisa.
verify(row).setSomething(value);
verify(row).setSomethingElse(anotherValue);
verify(row).editABunchMoreStuff();
verify(row).saveToDatabase();
verifyNoMoreInteractions(row);
Outras dicas
Não 100% sobre o tópico, mas eu estava apenas procurando encontrar o oposto da verificação, e esse foi o único resultado relevante, acaba depois que eu estava depois do Mockito.VerififyZeroInteractions (simulado);
Basta entrar em que mais alguém acaba aqui procurando por isso ...
Esta pergunta me levou a fazer algumas melhorias no Verificações API in Jmockit (Disponível na próxima versão 0.983).
A solução que encontrei permite que você escreva (em um método de teste):
new VerificationsInOrder() {{
unverifiedInvocations();
row.saveToDababase();
}};
... se você deseja verificar apenas se um determinado método é chamado após todo o resto. Para verificar isso, acontece antes da Todas as outras invocações, basta mover a chamada para o topo. Isso realmente se aplica a qualquer sequência de invocações consecutivas.
Se, além da verificação acima, você também deseja verificar se alguns outros métodos são chamados em qualquer ordem, um segundo verificações O bloco pode ser adicionado ao teste (antes ou depois do outro bloco, não importa):
new Verifications() {{
row.setSomething(value);
row.setSomethingElse(anotherValue);
}};
Embora um pouco longo devido ao uso de classes internas anônimas, essa sintaxe é simples e flexível; Observe como ele adiciona estrutura ao teste e evita a repetição de chamadas de método (como verify(...)
). Há mais do que descrevi aqui (Hamcrest Matchers, Counts de invocação etc.) e não se limita à verificação de métodos de instância (métodos e construtores estáticos podem ser ridicularizados e verificados da mesma maneira).