mocking - method - ¿Cómo negar un ArgumentMatcher en Mockito?
mockito spy (3)
He creado un ArgumentMatcher
,
private class IsListOf2Elements implements ArgumentMatcher<List<String>>{
@Override
public boolean matches(List<String> argument) {
return ((List<String>)argument).size()==2;
}
}
Quiero negar esta coincidencia, por lo que coinciden cuando el tamaño no es 2,
Mockito.doReturn(false).when(mock).addAll(Mockito.argThat(AdditionalMatchers.not(new IsListOf2Elements())));
Pero esto no es correcto. Yo obtengo,
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
No matchers found for additional matcher Not(?)
-> at my.test.own.Mockito_aTest.test4e(Mockito_aTest.java:136)
Como referencia, tenga en cuenta que los matchers de Hamcrest y los matchers de Mockito se comportan de manera muy diferente . Los objetos Matcher sin estado de Hamcrest representan la función de coincidencia como una instancia, y se pueden envolver para invertir sus resultados; Los "calificadores registrados" de Mockito solo funcionan a través de efectos secundarios.
argThat
adapta un matcher Hamcrest en un matcher Mockito, Hamcrest''s CoreMatchers.not
invierte un matcher Hamcrest, y Mockito''s AdditionalMatchers.not
invierte un matcher Mockito (a través de efectos secundarios). Esto es parte de la razón por la que CoreMatchers.not
siempre devuelve un Matcher<T>
, mientras que AddionalMatchers.not
devuelve una T
arbitraria; está operando en el estado de Mockito que no puedes ver.
Esto le da el siguiente comportamiento:
// BAD: Don''t use AdditionalMatchers to invert a Hamcrest matcher.
doReturn(false).when(mock).addAll(
Mockito.argThat(AdditionalMatchers.not(new IsListOf2Elements())));
// GOOD: Use AdditionalMatchers to invert a Mockito matcher. (See ericj''s answer.)
doReturn(false).when(mock).addAll(
AdditionalMatchers.not(Mockito.argThat(new IsListOf2Elements())));
// ALSO GOOD: Use CoreMatchers to invert a Hamcrest matcher. (See troig''s answer.)
doReturn(false).when(mock).addAll(
Mockito.argThat(CoreMatchers.not(new IsListOf2Elements())));
Si la excepción que está haciendo tiene que ver con el comportamiento del troyano, también puede usar una anulación más específica para anular el comportamiento general además de la excepción específica.
Encontré la respuesta yo mismo. La vuelta está alrededor,
Mockito.doReturn(false).when(mock).addAll(AdditionalMatchers.not(Mockito.argThat(new IsListOf2Elements())));
La razón es que AdditionalMatchers.not
espera una coincidencia registrada, y Mockito.argThat
. Mockito.argThat
hace eso.
Parece ser que no puede usar un matcher personalizado como parámetro del método AdditionalMatchers.not
.
Sin embargo, puedes usar hamcrest org.hamcrest.CoreMatchers en su lugar. Esto debería funcionar:
Mockito.doReturn(false).when(mock).addAll(Mockito.argThat(CoreMatchers.not(new IsListOf2Elements())));
Espero eso ayude