Estoy introduciendo pruebas en un proyecto que hace un uso intensivo de operaciones IO (el sistema de archivos, en este caso). El sistema abre / cierra archivos constantemente, comprueba si existen archivos, los elimina, etc.
Pronto se hizo obvio que las burlas regulares no serían de mucha utilidad, ya que eso haría que mis pruebas fueran difíciles de configurar y razonar. Por otro lado, tener un sistema de archivos falso sería increíble y creo que bastante fácil de configurar.
Parece que los chicos de ruby lo hicieron de nuevo, y hay exactamente lo que estoy pidiendo en ruby: http://ozmm.org/posts/fakefs.html .
¿Hay algo remotamente similar para Java?
java
unit-testing
testing
mocking
elisio devorado
fuente
fuente
Respuestas:
Google tiene una implementación de código abierto en memoria de FileSystemProvider de Java 7. El proyecto se llama jimfs .
Si usa Java 6 o anterior, hay una alternativa: he usado Apache Commons VFS antes con gran éxito. Parece ser muy parecido al FileSystemProvider personalizado que otro respondedor mencionado está en Java 7.
Viene precargado con varias implementaciones de sistemas de archivos: Archivo, RAM, S / FTP y Jar, por nombrar algunas. También he visto un complemento para S3 .
fuente
Path
por accidente)En Java 6 y versiones anteriores es difícil porque a las clases les gusta
File
yFileInputStream
no proporcionan forma de enviar a diferentes "sistemas de archivos virtuales" en el espacio Java.En Java 7, hay soporte para sistemas de archivos virtuales; consulte Desarrollo de un proveedor de sistema de archivos personalizado . No sé si esto le permitirá hacer lo que quiere hacer, pero es un buen lugar para empezar a buscar.
En realidad, usted gana utilizando FileSystemProvider:
Implementas algo que (si se publica bajo una licencia de código abierto) podría ser muy útil para otras personas en tu puesto y para otros fines.
Se lo hace más fácil si decide cambiar a un FileSystemProvider en el que otra persona podría estar trabajando en este momento.
fuente
Puede usar
org.junit.rules.TemporaryFolder
desde el paquete JUnit :Ejemplo:
final TemporaryFolder testFolder = new TemporaryFolder(); testFolder.create(); final Path filePath = testFolder.newFile("input.txt").toPath(); final Path dirPath = testFolder.newFolder("subfolder").toPath();
Alternativamente, salga de la
.toPath()
pieza:final File filePath = testFolder.newFile("input.txt");
fuente
Puede abstraer el uso de
File
usando la intención de "algún lugar para escribir datos" cambiando su API para usar un enOutputStream
lugar de aFile
, luego pasar el API aFileOutputStream
en su código de producción, pero pasarlo aByteArrayOutputStream
de sus pruebas. AByteArrayOutputStream
es un flujo en memoria, por lo que es muy rápido y simplemente puede inspeccionar su contenido utilizando sus métodos; es perfecto para realizar pruebas. También está el correspondienteByteArrayInputStream
si desea leer datos.Los sistemas de archivos son generalmente bastante rápidos; a menos que estuvieras haciendo una gran cantidad de E / S de archivos en tus pruebas, no me molestaría.
Tenga en cuenta que la creación de un
File
objeto java no crea un archivo en el disco, es decir, el siguiente código no causa ningún cambio en el disco:File f = new File("somepath"); // doesn't create a file on disk
fuente
new File("xyz").getAbsolutePath()
no hace absolutamente nada en absoluto Excepto devolver la ruta que el archivo podría tener si existiera. No cambia el sistema de archivos; si el archivo no existe, todavía devuelve la cadena de la ruta y no crea un archivo. ¿Qué quisiste decir con "ver qué pasa"?File
no es final en mi OpenJDK 7.Jimfs , de Google, es un sistema de archivos NIO en memoria, ideal para pruebas.
fuente
Una forma sencilla sería utilizar la forma de su sistema de proporcionar un sistema de archivos basado totalmente en RAM: tempfs en Linux, un disco RAM en Windows.
fuente
MockFTPServer parece tener un par de implementaciones de sistemas de archivos falsos (Unix / Windows)
Parece que puede usar estas implementaciones de sistemas de archivos falsos de forma bastante separada de cualquier concepto de FTP. Estoy probando esto ahora exactamente para los mismos objetivos que ha descrito.
fuente
No estoy seguro acerca de marcos específicos, pero un enfoque general en términos de POO sería escribir algunas capas abstractas encima de cualquier código de acceso a archivos (¡interfaces en abundancia!) y quizás una fachada para facilitar el uso de operaciones comunes. luego simplemente simula una capa debajo del código que está probando actualmente y luego es esencialmente un sistema de archivos falso (o al menos el código que está probando no sabrá lo contrario).
Si busca usar un marco de inyección de dependencia para manejar esto, facilitará la capacidad de cambiar componentes para una implementación falsa de una interfaz. Si sigue los patrones de inversión de control, pasando cualquier dependencia al constructor de la clase que está probando, esto también facilitará la prueba.
public interface IFileSystem { IFileHandle Load(string path); //etc } public class ClassBeingTested { public ClassBeingTested(IFileSystem fileSystem) { //assign to private field } public void DoSomethingWithFileSystem() { //utilise interface to file system here //which you could easily mock for testing purposes //by passing a fake implementation to the constructor } }
Espero que mi java sea correcto, no he escrito java en mucho tiempo, pero espero que te enteres. ¡Ojalá no esté subestimando el problema aquí y siendo demasiado simplista!
por supuesto, todo esto es asumiendo que te refieres a verdaderas pruebas unitarias, es decir, probar las unidades de código más pequeñas posibles, y no un sistema completo. para las pruebas de integración se necesita un enfoque diferente.
fuente
ShrinkWrap del proyecto Arquillian busca incluir un sistema de archivos en memoria compatible con NIO
Puede crear un sistema de archivos simple en memoria haciendo lo siguiente:
fuente
Otros dos sistemas de archivos de memoria para Java son,
sistema de archivos de memoria
efímeros
Ambos implementan la api del sistema de archivos NIO.2.
fuente
Estaba buscando en Google "Fake java FileSystem" y encontré esta pregunta. Desafortunadamente, esto es todo lo que encontré. Así que escribí este sistema de archivos falso yo mismo: https://github.com/dernasherbrezon/mockfs
Lo estoy usando para simular IOExceptions durante la lectura / escritura de archivos. IOException podría ocurrir, por ejemplo, debido a que "no hay espacio en el disco", lo que es casi imposible de simular por otros medios.
fuente
Es un poco vieja y esta solución parece ser solo Linux, pero se ve bien https://www.google.co.il/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=tmpfs%20on% 20ubuntu
tmpfs es un directorio mapeado en memoria (los datos desaparecen al reiniciar). Una vez montados, los datos se pueden copiar en él y trabajar desde la memoria.
fuente