¿Hay alguna biblioteca o método para simular el sistema de archivos en C # para escribir pruebas unitarias? En mi caso actual, tengo métodos que verifican si existe cierto archivo y leen la fecha de creación. Puede que necesite más que eso en el futuro.
c#
unit-testing
mocking
pupeno
fuente
fuente
Respuestas:
Editar: instale el paquete NuGet
System.IO.Abstractions
.Este paquete no existía cuando esta respuesta fue aceptada originalmente. La respuesta original se proporciona para el contexto histórico a continuación:
fuente
Esta biblioteca imaginaria existe ahora, hay un paquete NuGet para System.IO.Abstraction , que abstrae el espacio de nombres System.IO.
También hay un conjunto de ayudantes de prueba, System.IO.Abstraction.TestingHelpers que, en el momento de la escritura, solo está implementado parcialmente, pero es un muy buen punto de partida.
fuente
Probablemente tendrá que crear un contrato para definir qué cosas necesita del sistema de archivos y luego escribir un contenedor alrededor de esas funcionalidades. En ese momento, podrás burlarte o rechazar la implementación.
Ejemplo:
fuente
Mi recomendación es utilizar http://systemwrapper.codeplex.com/, ya que proporciona contenedores para los tipos más utilizados en el espacio de nombres del sistema
fuente
He encontrado las siguientes soluciones para esto:
Termino usando todos los métodos anteriores, dependiendo de lo que estoy escribiendo. Pero la mayoría de las veces termino pensando que la abstracción está mal cuando escribo pruebas unitarias que llegan al IO.
fuente
Al usar System.IO.Abstraction y System.IO.Abstraction.TestingHelpers así:
En su clase de prueba, utiliza MockFileSystem () para simular el archivo e instanciar ManageFile como:
fuente
Puede hacerlo utilizando Microsoft Fakes sin la necesidad de cambiar su base de código, por ejemplo, porque ya estaba congelada.
Primero genere un ensamblaje falso para System.dll - o cualquier otro paquete y luego simule los retornos esperados como en:
fuente
Sería difícil burlarse del sistema de archivos en una prueba, ya que las API de archivos .NET no se basan realmente en interfaces o clases extensibles que se puedan burlar.
Sin embargo, si tiene su propia capa funcional para acceder al sistema de archivos, podría burlarse de eso en una prueba unitaria.
Como alternativa a la burla, considere crear las carpetas y archivos que necesita como parte de su configuración de prueba y eliminarlos en su método de desmontaje.
fuente
No estoy seguro de cómo se burlaría del sistema de archivos. Lo que podría hacer es escribir una configuración de dispositivo de prueba que cree una carpeta, etc. con la estructura necesaria para las pruebas. Un método de desmontaje lo limpiaría después de ejecutar las pruebas.
Editado para agregar: Al pensar en esto un poco más, no creo que quiera burlarse del sistema de archivos para probar este tipo de métodos. Si se burla del sistema de archivos para que devuelva verdadero si existe un determinado archivo y lo usa en su prueba de un método que verifica si ese archivo existe, entonces no está probando mucho de nada. Donde burlarse del sistema de archivos sería útil si quisiera probar un método que dependiera del sistema de archivos pero la actividad del sistema de archivos no fuera parte integral del método bajo prueba.
fuente
Para responder a su pregunta específica: No, no hay bibliotecas que le permitan simular llamadas de E / S de archivos (que yo sepa). Esto significa que la unidad "correctamente" que prueba sus tipos requerirá que tenga en cuenta esta restricción cuando defina sus tipos.
Nota rápida sobre cómo defino una prueba de unidad "adecuada". Creo que las pruebas unitarias deberían confirmar que obtienes el resultado esperado (ya sea una excepción, llamar a un método, etc.) proporcionó entradas conocidas. Esto le permite configurar las condiciones de prueba de su unidad como un conjunto de entradas y / o estados de entrada. La mejor manera que he encontrado para hacer esto es usar servicios basados en interfaz e inyección de dependencia para que cada responsabilidad externa a un tipo se proporcione a través de una interfaz que se pasa a través de un constructor o propiedad.
Entonces, con esto en mente, regresemos a su pregunta. Me he burlado de las llamadas al sistema de archivos creando una
IFileSystemService
interfaz junto con unaFileSystemService
implementación que es simplemente una fachada sobre los métodos del sistema de archivos mscorlib. Mi código luego usa losIFileSystemService
tipos mscorlib en lugar de los tipos. Esto me permite conectar mi estándarFileSystemService
cuando la aplicación se está ejecutando o simularIFileSystemService
en las pruebas de mi unidad. El código de la aplicación es el mismo independientemente de cómo se ejecute, pero la infraestructura subyacente permite que ese código se pruebe fácilmente.Reconoceré que es difícil usar el contenedor alrededor de los objetos del sistema de archivos mscorlib pero, en estos escenarios específicos, vale la pena el trabajo extra ya que las pruebas se vuelven mucho más fáciles y confiables.
fuente
Crear una interfaz y burlarse de ella para realizar pruebas es el camino más limpio. Sin embargo, como alternativa, podría echar un vistazo al marco Microsoft Moles .
fuente
La solución común es usar una API de sistema de archivos abstracto (como Apache Commons VFS para Java): toda la lógica de aplicación usa API y la prueba de unidad puede burlarse del sistema de archivos real con implementación de código auxiliar (emulación en memoria o algo así).
Para C # existe una API similar: NI.Vfs, que es muy similar a Apache VFS V1. Contiene implementaciones predeterminadas tanto para el sistema de archivos local como para el sistema de archivos en memoria (el último puede usarse en pruebas unitarias desde la caja).
fuente
Actualmente utilizamos un motor de datos patentado y su API no está expuesta como interfaces, por lo que apenas podemos probar nuestro código de acceso a datos. Luego fui con el enfoque de Matt y Joseph también.
fuente
Iría con la respuesta de Jamie Ide. No trates de burlarte de cosas que no escribiste. Habrá todo tipo de dependencias que no conocía: clases selladas, métodos no virtuales, etc.
Otro enfoque sería envolver los métodos apropiados con algo que se pueda burlar. por ejemplo, cree una clase llamada FileWrapper que permita el acceso a los métodos File pero es algo que puede burlarse.
fuente