¿Cómo usar ArgumentCaptor para tropezar?

161

En la documentación de Mockito y javadocs dice

Se recomienda usar ArgumentCaptor con la verificación pero no con el apéndice.

pero no entiendo cómo ArgumentCaptor se puede usar para tropezar. ¿Alguien puede explicar la declaración anterior y mostrar cómo ArgumentCaptor se puede usar para tropezar o proporcionar un enlace que muestre cómo se puede hacer?

No puedo decir
fuente
1
Explicación súper corta y agradable aquí: dzone.com/articles/…
Benj

Respuestas:

271

Suponiendo el siguiente método para probar:

public boolean doSomething(SomeClass arg);

Documentación Mockito dice que usted debe no utilizar captor de esta manera:

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);
assertThat(argumentCaptor.getValue(), equalTo(expected));

Debido a que solo puede usar matcher durante el apisonamiento:

when(someObject.doSomething(eq(expected))).thenReturn(true);

Pero la verificación es una historia diferente. Si su prueba necesita asegurarse de que este método fue llamado con un argumento específico, use ArgumentCaptory este es el caso para el que está diseñado:

ArgumentCaptor<SomeClass> argumentCaptor = ArgumentCaptor.forClass(SomeClass.class);
verify(someObject).doSomething(argumentCaptor.capture());
assertThat(argumentCaptor.getValue(), equalTo(expected));
Rorick
fuente
Gracias por la respuesta. Tengo una pregunta. En el tercer bloque de código sabemos que verdadero se devuelve solo cuando se espera que pase a doSomething. ¿Pero cuándo se devuelve verdadero en el segundo bloque de código? ¿O someObject siempre devuelve true para someMethod en ese caso?
No se puede decir
Hm, creo que quisiste decir "¿Pero cuándo se devuelve la verdad en el tercer bloque de código?". En el tercer bloque de código simplemente no nos importa el valor de retorno y lo dejamos por defecto. Para booleano es false, no true.
Rorick
No, conté todos los bloques de fondo gris como bloques de código. Incluyendo el primer trazador de líneas. Me refería a la línea cuando (someObject.doSomething (argumentoCaptor.capture ())). LuegoReturn (true);
No se puede decir
Oh, lo siento. Sí, en este caso verdadero será devuelto siempre.
Rorick
3
no estoy seguro de que la razón para "no usar con trozos" sea una razón simple. los emparejadores no nos dan el argumento esperado real (solo el tipo) y conducen a estar de acuerdo con las pruebas que pasan a pesar de los argumentos que podrían estar equivocados.
dtc
0

La línea

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);

haría lo mismo que

when(someObject.doSomething(Matchers.any())).thenReturn(true);

Entonces, usar el argumentoCaptor.capture () cuando el apilamiento no tiene valor agregado. El uso de Matchers.any () muestra mejor lo que realmente sucede y, por lo tanto, es mejor para la legibilidad. Con argumentoCaptor.capture (), no puede leer qué argumentos realmente coinciden. Y en lugar de usar any (), puede usar coincidencias más específicas cuando tenga más información (clase del argumento esperado), para mejorar su prueba.

Y otro problema: si utiliza el argumentoCaptor.capture () al realizar un apéndice, no queda claro cuántos valores debe esperar capturar después de la verificación. Queremos capturar un valor durante la verificación, no durante el apilamiento porque en ese momento todavía no hay ningún valor para capturar. Entonces, ¿qué capturan los captores de argumentos el método de captura durante el apisonamiento? o no captura nada? No tengo la respuesta a esta pregunta. Considero que es un comportamiento indefinido y no quiero usar un comportamiento indefinido.

Stefan Mondelaers
fuente
0

Hipotéticamente, si la búsqueda te llevó a esta pregunta, entonces probablemente quieras esto:

doReturn(someReturn).when(someObject).doSomething(argThat(argument -> argument.getName().equals("Bob")));

¿Por qué? Porque como yo, usted valora el tiempo y no lo va a implementar .equalssolo por el solo escenario de prueba.

Y el 99% de las pruebas se desmoronan con una devolución nula de Mock y en un diseño razonable evitaría la devolución nulla toda costa, usar Optionalo mudarse a Kotlin. Esto implica que verifyno es necesario usarlo tan a menudo y ArgumentCaptors es demasiado tedioso para escribir.

Berenjena
fuente