Simulación de Dependencias y Comportamiento con Mock en Pruebas Unitarias

Clase 14 de 19Curso de Unit Testing con C# y .NET

Resumen

¿Cómo simular el comportamiento de una dependencia en pruebas unitarias?

En el desarrollo de software, las pruebas unitarias son básicas para garantizar la calidad del código. Resulta crucial poder simular dependencias para evitar que estas interfieran en los resultados de las pruebas. Utilizar una librería como Mock nos permite manipular estas dependencias, asegurando que nuestras pruebas sean consistentes. Vamos a profundizar en cómo configurar estas simulaciones en un entorno de Visual Studio, específicamente con la clase StringOperation.

¿Qué función vamos a probar ahora?

Nos centramos en la función readFile de la clase StringOperation. Esta función tiene como objetivo leer un archivo y devolver el texto contenido en él. Sin embargo, depende de una interfaz para acceder al archivo, lo cual es una situación común cuando trabajamos con dependencias en el código. Este tipo de diseño nos permite abstraer la lógica de acceso al archivo, haciéndola más fácil de simular en pruebas unitarias. La interfaz que emplea esta función no se pasa a través del constructor de su clase, sino directamente como un parámetro.

¿Por qué simular la interfaz en las pruebas unitarias?

Un principio central de las pruebas unitarias es que deben ser completamente independientes. No deberían depender de archivos o servicios externos. Por eso es esencial simular cualquier interfaz o dependencia que interactúe con elementos externos como archivos. Hacemos esto usando la librería Mock para crear un mock específico del FileReader.

¿Cómo realizar la simulación con Mock?

  1. Crear el mock de la dependencia: Iniciamos estableciendo el mock de FileReader con la interfaz iFileReaderConnector.

    var mockFileReader = new Mock<iFileReaderConnector>();
    
  2. Configurar la simulación: Utilizamos el método Setup para definir el comportamiento simulado del método readString.

    mockFileReader
        .Setup(m => m.readString(It.IsAny<string>()))
        .Returns("readingFile");
    

    Con It.IsAny<string>(), permitimos que cualquier cadena se use como parámetro y siempre devuelva "readingFile".

  3. Ejecutar la prueba: Con el mock configurado, podemos ejecutar el método readFile y verificar que siempre devuelva el valor simulado, sin depender del archivo físico.

    Assert.Equal("readingFile", result);
    

¿Cómo verificar configuraciones alternativas?

Podemos observar el comportamiento al variar los parámetros. Por ejemplo, si cambiamos el nombre del archivo en el mock Setup y luego ejecutamos otra prueba, el resultado debería ser null si no hemos creado una configuración general. Esto se debe a que la configuración es específica del parámetro esperado.

Reflexión sobre la importancia de las pruebas unitarias independientes

Las pruebas que hemos creado ilustran un aspecto vital del desarrollo de software: la independencia de pruebas unitarias. Nos ayudamos de Mock para cubrir diversas situaciones y asegurarnos de tener un código robusto que no dependa de variables externas. Mantener nuestras pruebas de esta manera nos brinda confianza en cada segmento de código bajo prueba. Así, cualquier error puede ser aislado y corregido con rapidez.

Explorar más sobre estas herramientas y técnicas nos permitirá afinar nuestras habilidades, asegurar la calidad del software que escribimos, y enfrentar con seguridad proyectos más complejos. ¡Nos vemos en la próxima sesión para seguir profundizando en este fascinante mundo!