Pruebas de Integración con Dobles de Prueba en Aplicaciones

Clase 23 de 24Curso de Arquitecturas Limpias para Desarrollo de Software

Contenido del curso

Resumen

Probar software que depende de bases de datos, APIs externas o sistemas de terceros es uno de los retos más frecuentes en el desarrollo profesional. Entender cómo funcionan las pruebas de integración y los dobles de prueba permite verificar la lógica de la capa de aplicación sin necesidad de tener cada componente real disponible, rápido y controlado.

¿Qué elementos componen una prueba de integración?

En toda prueba de integración existen dos protagonistas. El primero es el sistema bajo prueba (SBP), que es el componente cuyo comportamiento queremos verificar; en el contexto de arquitectura limpia, suele ser el dominio o la capa de aplicación [0:20]. El segundo es el componente del cual se depende (CDD), es decir, aquello que el SBP necesita para cumplir su tarea: una base de datos, un CRM, un servicio externo o cualquier otra pieza de infraestructura [0:38].

La relación es directa: el SBP consume al CDD. Pero ese componente externo trae consigo una serie de dificultades que hay que resolver antes de poder escribir pruebas confiables.

¿Por qué las dependencias externas dificultan las pruebas?

Trabajar con componentes reales durante las pruebas introduce varios problemas concretos:

  • Acceso lento. Si la base de datos está en un servidor remoto, cada ejecución de prueba suma latencia [1:10].
  • Dificultad para controlar el resultado. Al no tener dominio total sobre el componente, predecir su respuesta exige preparaciones o inicializaciones adicionales [1:32].
  • Efectos colaterales. Una prueba que dispara envíos de correo electrónico puede impactar a usuarios reales cada vez que se ejecuta [1:55].
  • Disponibilidad limitada. Algunos sistemas solo están accesibles en producción, lo que impide pruebas locales [2:15].
  • Costo económico. APIs que cobran por llamada incrementan el gasto cuando las pruebas se ejecutan de forma continua [2:30].

Estas limitaciones hacen evidente la necesidad de un mecanismo que sustituya al componente real sin sacrificar la capacidad de verificación.

¿Qué son los dobles de prueba y por qué son esenciales?

Un doble de prueba es un objeto que se coloca en lugar del objeto real con la intención específica de poder ejecutar la prueba [2:52]. Al construirlo tú, controlas su comportamiento: qué devuelve, cuántas veces se invoca y con qué parámetros.

La duda natural es si reemplazar el componente real deja la prueba incompleta. La respuesta práctica es complementar con pruebas de extremo a extremo (end-to-end), que sí utilizan todos los objetos reales, pero se escriben en menor cantidad porque son costosas, lentas y difíciles de mantener [3:25].

Los dos tipos de dobles más utilizados son los mocks y los stubs. Ambos permiten configurar cómo debe comportarse la dependencia simulada para que el SBP pueda ejecutarse y sus resultados sean verificables [3:50].

¿Cómo se implementan mocks con Mockito en la práctica?

En el ejemplo de código del curso, se trabaja con una prueba de integración sobre el flight service utilizando Mockito, un framework ampliamente adoptado para la creación de mocks en Java [4:05].

El flujo consta de varios pasos claros:

  • Se crean mocks de las interfaces de los repositorios que utiliza el servicio. El framework genera automáticamente un objeto que implementa la interfaz sin conectarse a ninguna base de datos [4:20].
  • Se instancia el servicio inyectándole esos repositorios mockeados, reemplazando así al componente real [4:45].
  • Se inicializan los datos de prueba y se configura el comportamiento esperado: cuando se llame al repositorio para buscar una ruta, debe devolver un resultado específico [5:10].
  • Se ejecuta el código del servicio y se verifica el resultado, por ejemplo, que devuelva exactamente dos vuelos [5:35].

Pero la potencia no termina ahí. También es posible verificar interacciones: confirmar que el repositorio fue llamado exactamente una vez y con el parámetro correcto [5:55]. Esto otorga un control muy fino sobre el comportamiento del servicio sin depender de infraestructura real.

¿Por qué las pruebas validan la arquitectura limpia?

Toda la estructura de dominio, infraestructura e inyección de dependencias cobra sentido real cuando se puede testear de forma aislada [6:25]. Si no es posible probar cada capa de manera independiente, el beneficio de implementar una arquitectura limpia se diluye. Las pruebas de integración con dobles de prueba son precisamente el mecanismo que confirma que la separación de responsabilidades funciona.

Si sientes que el testing es un área por fortalecer, profundizar en rutas de automatización de pruebas te dará herramientas para escribir mocks más elaborados y cubrir escenarios cada vez más complejos. ¿Ya estás usando dobles de prueba en tus proyectos? Comparte tu experiencia y las dificultades que has encontrado.