Se si utilizza Mockito 2.1.0 o versione successiva e Java 8 o versione successiva, vedere la risposta this invece, è molto più semplice ora.
Ho trovato la risposta mentre scrivevo la domanda.
Sì, è possibile. Invece di utilizzare any(Bar.class)
è necessario implementare la propria istanza di ArgumentMatcher<T>
e utilizzare Mockito#argThat(Matcher)
, per esempio, diciamo che vogliamo controllare che i
è 5 ...
// in the test (could also be outside)
private static final class BarIs5 extends ArgumentMatcher<Bar> {
@Override
public boolean matches(Object argument) {
return ((Bar) argument).getI() == 5;
}
}
Poi verificare in questo modo: verify(mockedFoo).doThing(argThat(new BarIs5()));
Rilanciare una tacca aggiungendo i parametri del costruttore!
private static final class BarIsWhat extends ArgumentMatcher<Bar> {
private final int i;
public BarIsWhat(int i) {
this.i = i
}
@Override
public boolean matches(Object argument) {
return ((Bar) argument).getI() == i;
}
}
Poi verificare in questo modo: verify(mockedFoo).doThing(argThat(new BarIsWhat(5)));
Aggiornamento: Questo spuntato nella mia coda a causa di un badge e ho visto un po 'di margine di miglioramento.
Ho provato questo e funziona. Puoi usare un'espressione lambda che è molto più pulita (se non ti dispiace almeno gli avvertimenti cast non selezionati).
L'unico problema è che argThat
accetta un Hamcrest Matcher
che è non un @FunctionalInterface
. Fortunatamente, lo ArgumentMatcher
di Mockito è una classe astratta che lo estende e ha un solo metodo astratto.
Nella prova (o una certa posizione comune) effettuare un metodo come di seguito
private static <T> ArgumentMatcher<T> matches(Predicate<T> predicate) {
return new ArgumentMatcher<T>() {
@SuppressWarnings("unchecked")
@Override
public boolean matches(Object argument) {
return predicate.test((T) argument);
}
};
}
Ora, nel test che si può fare questo per usare un'espressione lambda:
verify(mockedFoo).doThing(argThat(matches((Bar arg) -> arg.getI() == 5)));