2012-08-23 17 views
11

cuenta la situación siguiente (esto no es el código de producción):PHPUnit: ¿Cómo me burlo de este sistema de archivos?

class MyClass { 
    public function myMethod() { 
     // create a directory 
     $path = sys_get_temp_dir() . '/' . md5(rand()); 
     if(!mkdir($path)) { 
      throw new Exception("mkdir() failed."); 
     } 

     // create a file in that folder 
     $myFile = fopen("$path/myFile.txt", "w"); 
     if(!$myFile) { 
      throw new Exception("Cannot open file handle."); 
     } 
    } 
} 

derecho, ¿cuál es el problema? la cobertura de código informa que esta línea no está cubierto:

throw new Exception("Cannot open file handle."); 

Qué es lo correcto, pero ya que estoy creando la carpeta anterior lógicamente parecería imposible que el fopen() a fallar (excepto tal vez en circunstancias extremas, como en el disco 100%).

Podría ignorar el código de la cobertura del código, pero eso es un tipo de trampa. ¿Hay alguna manera en que pueda simular el sistema de archivos para que pueda reconocer myFile.txt y se burle del sistema de archivos que no puede crear el archivo?

Respuesta

9

vfsStream es un stream wrapper para un virtual filesystem que es útil en pruebas unitarias para simular el sistema de archivos real. Puede instalarlo desde composer.

Más información en:

https://github.com/mikey179/vfsStream

https://phpunit.de/manual/current/en/test-doubles.html

+0

Quiero pasar el mkdir() y el fopen() falla con un vfs, pero ¿cómo configuro eso sin tener dos funciones separadas? –

+0

Compruebe 'Mocking the Filesystem' específicamente a partir de los ejemplos' 10.15' en el enlace 'phpunit.de' anterior. La ventaja de usar vfs es que no hay dependencias reales en el sistema de archivos original. – raidenace

1

Sí!

Debe inyectar la ruta completa de alguna manera, y no llame a sys_get_temp_dir() directamente en ese método.

Cualquier ruta no existente debería ocasionar un problema. No necesitas VFS para eso.

PERO obtendrá un E_NOTICE (¿o una advertencia quizás?) Antes de que se active la excepción. Así que probablemente primero deberías marcar is_writable y lanzar la excepción si devuelve falso.

+0

En esta situación, la ruta base es irrelevante, ya sea que la inyecte o no. –

+1

Es relevante. La manera más fácil y consistente de hacer que esto falle es cambiar la ruta base. Con 'sys_get_temp_dir' no puedes usar VSF, ya que esa ruta base siempre será una ruta real. – Evert

2

También podría dividir la función en 2 métodos, uno para crear la ruta y el otro para usarlo. Luego, se podrían realizar pruebas individuales para garantizar que se cree la ruta. Un segundo conjunto de pruebas podría verificar y capturar la excepción cuando intente usar una ruta incorrecta.

Cuestiones relacionadas