with test run mockitojunitrunner mock example java spring mockito

java - test - Cómo resolver la excepción de troquelado innecesario



spring test (9)

Al mirar una parte de su seguimiento de pila, parece que está tropezando con el dao.doSearch() otro lugar. Más como crear repetidamente los apéndices del mismo método.

Following stubbings are unnecessary (click to navigate to relevant line of code): 1. -> at service.Test.testDoSearch(Test.java:72) Please remove unnecessary stubbings or use ''silent'' option. More info: javadoc for UnnecessaryStubbingException class.

Considere la siguiente clase de prueba, por ejemplo:

@RunWith(MockitoJUnitRunner.class) public class SomeTest { @Mock Service1 svc1Mock1; @Mock Service2 svc2Mock2; @InjectMock TestClass class; //Assume you have many dependencies and you want to set up all the stubs //in one place assuming that all your tests need these stubs. //I know that any initialization code for the test can/should be in a //@Before method. Lets assume there is another method just to create //your stubs. public void setUpRequiredStubs() { when(svc1Mock1.someMethod(any(), any())).thenReturn(something)); when(svc2Mock2.someOtherMethod(any())).thenReturn(somethingElse); } @Test public void methodUnderTest_StateUnderTest_ExpectedBehavior() { // You forget that you defined the stub for svcMock1.someMethod or //thought you could redefine it. Well you cannot. That''s going to be //a problem and would throw your UnnecessaryStubbingException. when(svc1Mock1.someMethod(any(),any())).thenReturn(anyThing);//ERROR! setUpRequiredStubs(); } }

Prefiero considerar la refactorización de sus pruebas para tropezar donde sea necesario.

Mi código es el siguiente

@RunWith(MockitoJUnitRunner.class) public class MyClass { private static final String code ="Test"; @Mock private MyClassDAO dao; @InjectMocks private MyClassService Service = new MyClassServiceImpl(); @Test public void testDoSearch() throws Exception { final String METHOD_NAME = logger.getName().concat(".testDoSearchEcRcfInspections()"); CriteriaDTO dto = new CriteriaDTO(); dto.setCode(code); inspectionService.searchEcRcfInspections(dto); List<SearchCriteriaDTO> summaryList = new ArrayList<SearchCriteriaDTO>(); inspectionsSummaryList.add(dto); when(dao.doSearch(dto)).thenReturn(inspectionsSummaryList);//got error in this line verify(dao).doSearchInspections(dto); } }

Me estoy poniendo por debajo de la excepción

org.mockito.exceptions.misusing.UnnecessaryStubbingException: Unnecessary stubbings detected in test class: Test Clean & maintainable test code requires zero unnecessary code. Following stubbings are unnecessary (click to navigate to relevant line of code): 1. -> at service.Test.testDoSearch(Test.java:72) Please remove unnecessary stubbings or use ''silent'' option. More info: javadoc for UnnecessaryStubbingException class. at org.mockito.internal.exceptions.Reporter.formatUnncessaryStubbingException(Reporter.java:838) at org.mockito.internal.junit.UnnecessaryStubbingsReporter.validateUnusedStubs(UnnecessaryStubbingsReporter.java:34) at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:49) at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:103) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

Por favor, ayúdame a resolver


Al principio debes verificar tu lógica de prueba. Por lo general, hay 3 casos. Primero, se está burlando del método incorrecto (cometió un error tipográfico o alguien cambió el código probado para que el método burlado ya no se use). En segundo lugar, su prueba falla antes de que se llame a este método. En tercer lugar, su lógica se equivoca si / cambia de rama en algún lugar del código, por lo que no se llama al método burlado.

Si este es el primer caso, siempre desea cambiar el método simulado por el utilizado en el código. Con el segundo y el tercero depende. Por lo general, solo debe eliminar este simulacro si no tiene uso. Pero a veces hay ciertos casos en las pruebas parametrizadas, que deberían tomar este camino diferente o fallar antes. Luego puede dividir esta prueba en dos o más, pero eso no siempre es atractivo. 3 métodos de prueba con posiblemente 3 proveedores de argumentos pueden hacer que la prueba parezca ilegible. En ese caso para JUnit 4, silencia esta excepción con

@RunWith(MockitoJUnitRunner.Silent.class)

anotación o si está utilizando el enfoque de regla

@Rule public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.LENIENT);

o (el mismo comportamiento)

@Rule public MockitoRule rule = MockitoJUnit.rule().silent();

Para las pruebas JUnit 5, puede silenciar esta excepción utilizando la anotación proporcionada en el mockito-junit-jupiter .

@ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) class JUnit5MockitoTest { }


En el caso de un proyecto grande, es difícil solucionar cada una de estas excepciones. Al mismo tiempo, no se recomienda usar Silent . He escrito un script para eliminar todos los trozos innecesarios dada una lista de ellos.

https://gist.github.com/cueo/da1ca49e92679ac49f808c7ef594e75b

Solo necesitamos copiar y pegar la salida de mvn y escribir la lista de estas excepciones usando regex y dejar que el script se encargue del resto.


Para mí, ni las @Rule ni @RunWith(MockitoJUnitRunner.Silent.class) funcionaron. Fue un proyecto heredado donde actualizamos a mockito-core 2.23.0.

Podríamos deshacernos de la UnnecessaryStubbingException usando:

Mockito.lenient().when(mockedService.getUserById(any())).thenReturn(new User());

en vez de:

when(mockedService.getUserById(any())).thenReturn(new User());

No es necesario decir que debería mirar el código de prueba, pero necesitamos compilar todo y ejecutar las pruebas en primer lugar;)


Reemplace @RunWith(MockitoJUnitRunner.class) con @RunWith(MockitoJUnitRunner.Silent.class) .


Si estás usando este estilo en su lugar:

@Rule public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);

reemplazarlo con:

@Rule public MockitoRule rule = MockitoJUnit.rule().silent();


Tuve UnnecessaryStubbingException cuando intenté usar los métodos when en un objeto Spy. Mockito.lenient() silenció la excepción pero los resultados de la prueba no fueron correctos.

En el caso de los objetos Spy, uno tiene que llamar a los métodos directamente.

@ExtendWith(MockitoExtension.class) @RunWith(JUnitPlatform.class) class ArithmTest { @Spy private Arithm arithm; @Test void testAddition() { int res = arithm.add(2, 5); // doReturn(7).when(arithm).add(2, 5); assertEquals(res, 7); } }


El silencio no es una solución. Necesitas arreglar tu simulacro en tu prueba. Ver documentación oficial here .

Los apéndices innecesarios son llamadas de método apurado que nunca se realizaron durante la ejecución de la prueba (véase también MockitoHint), por ejemplo:

//code under test: ... String result = translator.translate("one") ... //test: ... when(translator.translate("one")).thenReturn("jeden"); // <- stubbing realized during code execution when(translator.translate("two")).thenReturn("dwa"); // <- stubbing never realized ...

Observe que uno de los métodos apagados nunca se realizó en el código bajo prueba, durante la ejecución de la prueba. El trozo perdido podría ser un descuido del desarrollador, el artefacto de copiar y pegar o el efecto de no comprender la prueba / código. De cualquier manera, el desarrollador termina con un código de prueba innecesario. Para mantener la base de código limpia y mantenible, es necesario eliminar el código innecesario. De lo contrario, las pruebas son más difíciles de leer y razonar.

Para obtener más información sobre la detección de trozos no utilizados, consulte MockitoHint.


when(dao.doSearch(dto)).thenReturn(inspectionsSummaryList);//got error in this line verify(dao).doSearchInspections(dto);

when aquí configura tu simulacro para hacer algo. Sin embargo, ya no usa este simulacro después de esta línea (aparte de hacer una verify ). Mockito te advierte que la línea when tiene sentido. ¿Quizás cometiste un error lógico?