Cuando empiezas a escribir pruebas unitarias en .NET, te topas rápido con un problema: tu código depende de cosas que no controlas, como bases de datos, servicios en la nube o librerías externas. Aquí entra el concepto de mock, una técnica que te permite simular esas dependencias para que tus pruebas se enfoquen solo en la lógica que tú escribiste.
Esta guía es útil para desarrolladores .NET que quieren escribir pruebas unitarias confiables, rápidas e independientes usando la librería Moq.
¿Qué es un mock y por qué lo necesitas en tus pruebas?
Un mock es un objeto imitado o simulado que reemplaza una dependencia real dentro de tu código durante la ejecución de una prueba. La idea es evitar que tu prueba dependa de elementos externos que no puedes controlar.
Esas dependencias pueden ser muchas cosas:
- Servicios de AWS o Azure.
- Librerías de terceros ajenas a tu proyecto.
- Clases, interfaces o clases abstractas externas.
- Conexiones a bases de datos.
La regla es sencilla: simulas lo que no controlas y dejas el código real para lo que sí pertenece a tu proyecto. Así, tu prueba mide tu lógica, no la del mundo exterior.
¿Qué es un mock en pruebas unitarias? Es un objeto que imita el comportamiento de una dependencia real, devolviendo datos o respuestas predefinidas para que tu prueba se ejecute sin acceder al servicio original.
¿Cómo funcionan los mocks cuando un componente tiene varias dependencias?
Imagina un componente con dos dependencias externas. En lugar de dejar que tu prueba se conecte a esos servicios reales, conviertes esas dependencias en mocks: objetos que devuelven un dato específico o simulan un comportamiento concreto.
Un caso muy común es el de las bases de datos. Una prueba unitaria no debería depender de una base de datos real. Si tu código ejecuta un query, lo que haces es crear un mock que simule el resultado de ese query y luego validar tu lógica con ese valor simulado. La prueba se vuelve rápida, repetible y no falla porque la base de datos esté caída.
¿Qué pasa si pruebas con dependencias reales?
Tu prueba deja de ser unitaria. Empieza a depender de la red, del estado de una base de datos, de credenciales y de servicios que pueden cambiar. El resultado: pruebas lentas, frágiles y difíciles de reproducir.
¿Cómo se usa la librería Moq en .NET para simular dependencias?
Moq es la librería más popular en .NET para crear mocks. Te permite definir cómo debe comportarse una dependencia simulada dentro de tus pruebas, sin tocar el código de producción.
Piensa en un escenario real: un servicio de tareas que se usa desde una API o un proyecto web. Ese servicio tiene dos dependencias típicas:
- Entity Framework, el ORM más usado en .NET, para conectarse a la base de datos.
- Un servicio de logging que registra eventos como queries, actualizaciones y guardados.
Ninguna de las dos forma parte de la lógica que quieres probar. Lo que te importa es validar el comportamiento del servicio en sí.
¿Qué cosas sí debes probar en un servicio?
La lógica que tú escribiste y controlas. Por ejemplo:
- Si el servicio hace un query y luego aplica un filtro sobre los resultados.
- Si el servicio ordena una lista después de traerla de la base.
- Si el servicio busca un elemento dentro de una colección y le aplica un cambio.
Eso es lo que entra en una prueba unitaria. El cómo se conecta a la base o cómo escribe en el log queda fuera, porque no es tu lógica de negocio.
¿Cómo simular una base de datos y un sistema de logging con Moq?
Con Moq puedes inyectar mocks que reemplacen Entity Framework y el sistema de logging. Una opción frecuente es usar una base de datos en memoria, donde el sistema de pruebas crea una base simulada con la que tu código interactúa como si fuera real.
Para el logging, la estrategia suele ser distinta. El logging existe para recolectar datos y métricas, pero no afecta la lógica del producto. Por eso, el mock del logger normalmente no hace nada: lo inyectas como dependencia, el servicio cree que está registrando eventos, y tu prueba ignora ese paso.
¿Por qué no se prueba el logging en pruebas unitarias? Porque las pruebas unitarias validan lógica de negocio, y el logging es un sistema auxiliar de observabilidad que no afecta el resultado funcional del código.
¿Cuándo usar una base de datos en memoria con Moq? Cuando necesitas que tu código interactúe con un contexto de Entity Framework durante la prueba, pero sin conectarte a una base real. La base en memoria simula ese comportamiento dentro del proceso de prueba.
Con esto en mente, el siguiente paso es ver Moq aplicado a escenarios concretos dentro de un proyecto .NET, donde podrás identificar qué inyectar, qué simular y qué dejar tal cual. Cuéntame en los comentarios qué dependencia te ha costado más mockear en tus proyectos.