Translate

jueves, 25 de junio de 2026

@MockitoSpyBean en Spring Framework


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