Testeando Unitariamente el Sistema de Archivos en PHP

Un truco para desacoplar tus tests del sistema de archivos local.

Cada vez que hacemos una llamada a file_get_contents o fwrite o cualquiera de las funciones de sistema de archivos en PHP, estamos acoplando nuestro código al sistema de archivos. Lo que quiero decir con esto es que nuestro código necesita un sistema de archivos para funcionar.

Si estuviésemos usando una abstracción de sistema de archivos como Flysystem (lo cual recomiendo bastante), basta solo con hacer un mock de la clase de sistema de archivos y nuestro problema está resuelto. Podemos testear esto unitariamente sin ningún problema. Aquí no hay acoplamiento a una implementación, sino a una abstracción, lo cual es muy bueno.

Sin embargo, cuando usamos las funciones nativas de PHP para el sistema de archivos, el asunto se complica. Una función no puede ser mockeada, por lo que necesitamos un sistema de archivos real. La primera intuición de muchos desarrolladores es usar el sistema de archivos del host para escribir los tests. Sin embargo, esto deja de ser una prueba unitaria, y se convierte en una prueba funcional (estamos golpeando directamente el sistema de archivos) y esto podría causar errores en un pipeline CI/CD (sin permisos de escritura, por ejemplo) o ser muy dependiente del ambiente específico.

¡VfsStream al rescate!

Cuando me encontré con este problema, me dediqué a buscar una solución y encontré una librería genial: vfsStream. Lo que hace es registrar un stream wrapper de PHP que simula un sistema de archivos real, pero en memoria (lo que significa que cuando nuestros tests terminan, el estado se pierde).

Supongamos que tienes una clase llamada FilesystemCacheDriver cuyo propósito es cachear información usando el sistema de archivos. Ésta toma como argumento en el constructor el directorio raíz de la caché.

PHP
FilesystemCacheDriver.php

Para testear la línea 23 con nuestro sistema de archivos virtual, lo único que tenemos que hacer es:

PHP
FilesystemCacheDriverTest.php

¡Y listo! Este test pasará independientemente del ambiente o la implementación de sistema de archivos en la que se encuentre, y hemos desacoplado nuestra prueba de su implementación. Esto es ahora una prueba unitaria real.

Leave a Reply

Your email address will not be published. Required fields are marked *