Si trabajás con pruebas en Spring Boot, seguramente utilizaste @SpyBean para observar el comportamiento de un bean real y verificar sus interacciones.
Sin embargo, a partir de las versiones más recientes de Spring, @SpyBean fue reemplazado por @MockitoSpyBean, una nueva anotación que forma parte del soporte oficial de Mockito en Spring Framework.
¿Por qué aparece @MockitoSpyBean?
Durante años Spring Boot ofreció:
- @MockBean
- @SpyBean
para integrar Mockito con el contexto de Spring.
Con la evolución del framework, estas anotaciones fueron reemplazadas por:
- @MockitoBean
- @MockitoSpyBean
que proporcionan una integración más consistente y alineada con Mockito.
Un Spy es una instancia real envuelta por Mockito.
Esto significa que:
- Los métodos reales se ejecutan normalmente.
- Podemos verificar invocaciones.
- Podemos modificar comportamientos específicos cuando sea necesario.
Por eso un Spy resulta ideal cuando queremos observar el comportamiento de un bean sin reemplazarlo completamente.
Supongamos el siguiente servicio:
@Service
public class EmailService {
public void send(String to, String message) {
System.out.println("Sending email to " + to);
}
}
Y un servicio que lo utiliza:
@Service
public class UserService {
private final EmailService emailService;
public UserService(EmailService emailService) {
this.emailService = emailService;
}
public void register(String email) {
emailService.send(email, "Welcome!");
}
}
Utilizando @MockitoSpyBean
@SpringBootTest
class UserServiceTest {
@Autowired
private UserService userService;
@MockitoSpyBean
private EmailService emailService;
@Test
void shouldSendWelcomeEmail() {
userService.register("john@example.com");
verify(emailService)
.send("john@example.com", "Welcome!");
}
}
La prueba utiliza el bean real de Spring, pero Mockito registra las interacciones permitiéndonos verificar llamadas y argumentos.
Aunque el Spy ejecuta la implementación real, podemos modificar métodos específicos:
doNothing()
.when(emailService)
.send(anyString(), anyString());
De esta manera evitamos ejecutar la lógica real mientras seguimos verificando las invocaciones.
En la mayoría de los proyectos Spring Boot basta con incluir:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
Si usas gradle:
testImplementation 'org.springframework.boot:spring-boot-starter-test'
Esta dependencia incorpora Mockito y las utilidades de testing de Spring.
@MockitoBean vs @MockitoSpyBean ¿Cuándo conviene usarlo?
@MockitoSpyBean resulta útil cuando:
- Queremos verificar interacciones sobre un bean real.
- Necesitamos conservar parte de la lógica original.
- Queremos evitar crear mocks complejos.
- Estamos realizando pruebas de integración con Spring.
Los Spies son poderosos, pero también pueden volver las pruebas más sensibles a cambios internos de implementación.
Como regla general:
- Utilizá @MockitoBean para aislar dependencias.
- Utilizá @MockitoSpyBean cuando necesites observar el comportamiento real de un bean.
@MockitoSpyBean representa la evolución natural de @SpyBean y es la alternativa recomendada en las versiones actuales de Spring.
Permite combinar la ejecución real de un componente con todas las capacidades de verificación de Mockito, logrando pruebas más expresivas y fáciles de diagnosticar cuando algo falla.
Y si no entienden la imagen es Mr Bean de espía ;)

No hay comentarios.:
Publicar un comentario