Ho appena letto un sacco di argomenti contro l'utilizzo di Mockito.reset
e non ho molto senso. Metti diversamente, sono d'accordo in generale, ma c'è sempre un caso che sembra usare reset
è utile o addirittura necessario.
Molto semplificata, la mia classe sotto test è una mappa incapsulata come
class Handler {
private final Map<String, String> map;
public void handle(RequestResponse rr) {
if (rr.isPut()) {
map.put(rr.key(), rr.value());
rr.response("OK");
} else {
rr.response(map.get(rr.key());
}
}
}
Per provarlo, faccio finta RequestResponse
e faccio qualcosa di simile a
when(rr.isPut()).thenReturn(true);
when(rr.key()).thenReturn("key");
when(rr.value()).thenReturn("value");
handler.handle(rr);
verify(rr).response("OK");
reset(rr);
when(rr.isPut()).thenReturn(false);
when(rr.key()).thenReturn("key");
handler.handle(rr);
verify(rr).response("value");
reset(rr);
when(rr.isPut()).thenReturn(false);
when(rr.key()).thenReturn("anotherKey");
handler.handle(rr);
verify(rr).response(null);
Posso vedere, sto testando tre cose contemporaneamente:
- risposta corretta dopo "metti"
- il valore corretto restituito da get con la stessa chiave
-
null
restituito da get con un'altra chiave
Posso immaginare i motivi per separare gli ultimi due test. Tuttavia, entrambi hanno bisogno del primo e ho ancora bisogno di un reset
in mezzo? Oppure no?
Aggiornamento
Nel frattempo la classe sotto test è diventata un po 'più complicata e la necessità di reset
è più grande. È una sorta di macchina a stati e il test assomiglia a
- ripeti quanto segue su percorsi diversi
- prova un passaggio illegale e attendi un'eccezione
- prova un altro passaggio illegale e attendi un'eccezione
- fai un passaggio legale e verifica l'output
In realtà ho solo bisogno di due metodi, uno che verifica l'eccezione per un passaggio illegale e l'altro che verifica l'output corretto per un passaggio legale. L'esecuzione di un passaggio illegale non deve cambiare lo stato, quindi è sicuro mischiarlo.
Considera questo esempio: se l'unica sequenza di input valida era A, B, C
(tre passaggi) e gli output corrispondenti erano a, b, c
, allora un test assomiglia a
checkException("B")
checkException("C")
checkOutput("A", "a")
checkException("A")
checkException("C")
checkOutput("B", "b")
checkException("A")
checkException("B")
checkOutput("C", "c")
checkException("A")
checkException("B")
checkException("C")
percorre l'intero percorso e verifica tutto. Ci vorranno molti test "normali" di verifica delle condizioni per ottenere lo stesso risultato, giusto?