Mockito moderno
La versión actual trae cambios importantes respecto a las ramas 2.x y 3.x:
Mock-maker inline por defecto: el inline-mock-maker ya no requiere configuración manual en src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker. Permite mockear clases final, métodos final y métodos estáticos sin añadir un fichero de recursos ni el artefacto mockito-inline. Es la opción predeterminada para proyectos nuevos.
Soporte completo de Java 21 y superiores: ciclo de integración continua con JDKs LTS, compatibilidad con registros (record), selladas (sealed) y clases ocultas generadas por el compilador. No hay advertencias de Byte Buddy en proyectos modernos bien configurados.
Mocking estable de métodos estáticos: Mockito.mockStatic(Clase.class) sustituye a la solución histórica de PowerMock para interceptar métodos estáticos. Se utiliza dentro de un bloque try-with-resources para limitar el scope al test y evitar fugas entre pruebas.
BDDMockito completo: el estilo given/willReturn/then.should es equivalente al clásico when/thenReturn/verify y está recomendado en proyectos que aplican BDD o que integran Mockito con Cucumber, Spring Cloud Contract o similares.
Anotación Captor mejorada: Captor resuelve los genéricos anidados correctamente (ArgumentCaptor<List<Pedido>>) sin warnings de tipos y se combina con Mock, Spy e InjectMocks en la misma clase de test.
Integración moderna con Spring Boot: la plataforma Spring Framework y Spring Boot introducen @MockitoBean y @MockitoSpyBean como sustitución directa de las anotaciones clásicas @MockBean y @SpyBean, con soporte de configuración por TestExecutionListener y recarga controlada del contexto.
PowerMock queda retirado del stack de referencia. Todos los escenarios que antes requerían PowerMockito (estáticos, constructores, clases final) se cubren con Mockito puro en la versión actual.
Tipos de dobles de prueba
Mockito soporta varios tipos de dobles de prueba con una API unificada:
- Mock: objeto totalmente simulado que no ejecuta lógica real. Los métodos devuelven valores neutros por defecto (null, 0, false, colecciones vacías) salvo que se configure stubbing explícito.
- Spy: envoltorio sobre una instancia real. Los métodos ejecutan la lógica original por defecto y se pueden sobrescribir selectivamente con
doReturn/doThrow/doAnswer. - Captor: herramienta para capturar los argumentos con los que se invoca a un método del mock, habilitando aserciones detalladas después del acto.
- MockedStatic: handle que intercepta los métodos estáticos de una clase dentro del scope de un
try-with-resourcesy los restaura al cerrar.
flowchart LR
A[Crear mock] --> B[Stubbing when/thenReturn]
B --> C[Ejecutar código bajo prueba]
C --> D[Verify invocaciones]
D --> E[Capturar argumentos]
E --> F[Asserts detallados]
El ciclo habitual de un test con Mockito es: crear el mock, configurar su comportamiento con stubbing, invocar al código bajo prueba, verificar las interacciones esperadas y, si hace falta, inspeccionar argumentos con un captor.
Mock vs spy vs mocking parcial
La diferencia entre mock, spy y mocking parcial es fundamental para decidir qué herramienta aplicar en cada test:
flowchart TD
A[Qué necesito?] --> B{Ejecuto lógica real?}
B -->|No, todo simulado| C[Mock puro con Mock]
B -->|Si, lógica real + algun método fake| D[Spy sobre instancia real]
D --> E[doReturn when sobre método concreto]
B -->|Mockito crea mock y sobrescribo pocos métodos| F[Mocking parcial con Mock]
F --> G[doCallRealMethod when sobre métodos concretos]
El mock puro se utiliza cuando la dependencia no debe ejecutar nada. El spy se usa cuando se quiere ejecutar la lógica real y solo sobrescribir métodos puntuales. El mocking parcial con doCallRealMethod es raro y suele indicar un diseño que conviene revisar.
MockitoExtensión e integración con JUnit 6
La forma recomendada de utilizar Mockito con JUnit Jupiter es mediante @ExtendWith(MockitoExtension.class). Esta extensión procesa las anotaciones @Mock, @Spy, @InjectMocks y @Captor antes de cada test y valida el uso estricto de stubs al finalizar.
flowchart LR
A[JUnit 6 ciclo] --> B[MockitoExtensión beforeEach]
B --> C[Inicializa campos Mock Spy Captor]
C --> D[Crea objeto InjectMocks]
D --> E[Ejecuta test]
E --> F[afterEach valida stubbing]
F --> G[Detecta stubs no usados en strict mode]
La extensión opera en modo STRICT_STUBS por defecto: detecta stubbings configurados pero nunca invocados y argumentos que no coinciden con los esperados, lo que ayuda a mantener tests precisos y sin basura.
InjectMocks: resolución por constructor y setter
@InjectMocks resuelve automáticamente las dependencias del sujeto bajo prueba a partir de los campos anotados con @Mock y @Spy. El orden de resolución es determinista:
flowchart TD
A[InjectMocks sobre la clase bajo prueba] --> B[1. Intenta inyección por constructor]
B --> C{Constructor con mas parámetros encaja?}
C -->|Si| D[Crea instancia con los mocks]
C -->|No| E[2. Inyección por setter]
E --> F{Setters coinciden por tipo?}
F -->|Si| G[Invoca setters con los mocks]
F -->|No| H[3. Inyección por campo]
H --> I[Asigna mocks por reflexion]
Si Mockito no encuentra un candidato para alguna dependencia, la deja como null. Por eso es importante declarar @Mock para todas las dependencias relevantes antes de anotar el sujeto con @InjectMocks.
Estilo BDDMockito
BDDMockito propone una sintaxis alineada con Behaviour-Driven Development, separando el test en tres secciones claras:
flowchart LR
A[given stubbing] --> B[when acción]
B --> C[then should verify]
A -.->|BDDMockito.given willReturn| A
C -.->|BDDMockito.then should| C
El esquema given/when/then es especialmente útil cuando el test forma parte de una especificación escrita por negocio, o cuando el equipo adopta una convención de nomenclatura común con los escenarios de BDD.
Spring Boot testing: capas y MockitoBean
La suite de testing de Spring Boot combina Mockito con slices de contexto para aislar capas de la aplicación sin instanciar todo el contenedor:
flowchart TD
A[Test en Spring Boot] --> B{Qué quiero probar?}
B -->|Solo lógica de servicio| C[MockitoExtensión + Mock + InjectMocks]
B -->|Capa web REST| D[WebMvcTest + MockitoBean]
B -->|Repositorio JPA| E[DataJpaTest sin mocks]
B -->|Flujo completo| F[SpringBootTest + MockitoBean]
D --> G[MockMvc como cliente HTTP simulado]
F --> H[MockitoSpyBean para verificar colaboradores reales]
@MockitoBean reemplaza un bean del ApplicationContext por un mock de Mockito. @MockitoSpyBean envuelve el bean real como un spy. Ambas anotaciones sustituyen a las clásicas @MockBean y @SpyBean del paquete org.springframework.boot.test.mock.mockito.
Del mundo PowerMock al mockStatic moderno
Durante años, los tests que necesitaban mockear estáticos, constructores o métodos privados recurrían a PowerMock. Mockito moderno cubre la mayoría de esos escenarios sin librerías externas:
flowchart LR
A[Escenario histórico] --> B{Qué necesito?}
B -->|Método estático| C[Mockito.mockStatic en try-with-resources]
B -->|Constructor| D[Mockito.mockConstruction en try-with-resources]
B -->|Clase final o método final| E[Inline mock maker por defecto]
B -->|Método privado| F[Refactorizar hacia package-private o colaborador]
C -.->|Sustituye| G[PowerMockito.mockStatic]
D -.->|Sustituye| H[whenNew de PowerMock]
PowerMock bloquea habitualmente la actualización del JDK y de JUnit. En proyectos modernos se retira en favor de Mockito puro.
Qué incluye este itinerario
- Fundamentos: qué es el mocking, creación de mocks con
mock()y@Mock, comportamiento por defecto y stubbing conwhen/thenReturn,thenThrow,thenAnswery la sintaxisdoReturn/when. - Verificación: uso de
verifycon modos (times,never,atLeast,atMost), argument matchers (any,eq,argThat), captura de argumentos conArgumentCaptor, verificación de orden conInOrdery verificación contimeout/after. - Avanzado: spies y mocking parcial,
@InjectMockscon resolución por constructor y setter, estilo BDDMockito, mocking de métodos estáticos conmockStatic, integración con Spring Boot (@MockitoBean,@MockitoSpyBean,@WebMvcTest).
Documentación oficial
La documentación oficial de Mockito está en https://site.mockito.org/ y la referencia completa de la API en https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html. La guía de testing de Spring Boot se encuentra en https://docs.spring.io/spring-boot/reference/testing/index.html.