Tengo un método privado en mi clase de prueba que construye un Bar
objeto de uso común . El Bar
constructor llama al someMethod()
método en mi objeto burlado:
private @Mock Foo mockedObject; // My mocked object
...
private Bar getBar() {
Bar result = new Bar(mockedObject); // this calls mockedObject.someMethod()
}
En algunos de mis métodos de prueba que quiero verificar someMethod
también fue invocado por esa prueba en particular. Algo como lo siguiente:
@Test
public void someTest() {
Bar bar = getBar();
// do some things
verify(mockedObject).someMethod(); // <--- will fail
}
Esto falla porque el objeto burlado se había someMethod
invocado dos veces. No quiero que mis métodos de prueba se preocupen por los efectos secundarios de mi getBar()
método, ¿sería razonable restablecer mi objeto simulado al final de getBar()
?
private Bar getBar() {
Bar result = new Bar(mockedObject); // this calls mockedObject.someMethod()
reset(mockedObject); // <-- is this OK?
}
Pregunto, porque la documentación sugiere que restablecer objetos simulados es generalmente indicativo de malas pruebas. Sin embargo, esto me parece bien.
Alternativa
La opción alternativa parece estar llamando:
verify(mockedObject, times(2)).someMethod();
lo que en mi opinión obliga a cada prueba a conocer las expectativas de getBar()
, sin ningún beneficio.
Mockito.clearInvocations(T... mocks)
Extraído de los documentos mockito .
Mi consejo es que intentes evitar usarlo
reset()
. En mi opinión, si llama dos veces a someMethod, eso debería probarse (tal vez sea un acceso a la base de datos u otro proceso largo del que desee ocuparse).Si realmente no te importa eso, puedes usar:
Tenga en cuenta que esto último podría causar un resultado falso, si llama a someMethod desde getBar, y no después (este es un comportamiento incorrecto, pero la prueba no fallará).
fuente
verify
a mi método privado (que estoy de acuerdo, probablemente no pertenezca allí). Agradezco sus comentarios sobre si su respuesta cambiaría.Absolutamente no. Como suele ser el caso, la dificultad que tiene para escribir una prueba limpia es una gran señal de alerta sobre el diseño de su código de producción. En este caso, la mejor solución es refactorizar su código para que el constructor de Bar no llame a ningún método.
Los constructores deben construir, no ejecutar la lógica. Tome el valor de retorno del método y páselo como un parámetro constructor.
se convierte en:
Si esto resultara en la duplicación de esta lógica en muchos lugares, considere crear un método de fábrica que pueda probarse independientemente de su objeto Bar:
Si esta refactorización es demasiado difícil, entonces usar reset () es una buena solución. Pero seamos claros: indica que su código está mal diseñado.
fuente