web-dev-qa-db-fra.com

Existe-t-il des frameworks Fake File System pour Java?

J'introduis des tests dans un projet qui fait un usage intensif des opérations IO (le système de fichiers, dans ce cas). Le système ouvre/ferme constamment des fichiers, vérifie si des fichiers existent, les supprime, etc.) .

Il est vite devenu évident que les moqueries régulières ne seraient pas très utiles, car cela rendrait mes tests difficiles à configurer et à raisonner. D'un autre côté, avoir un faux système de fichiers serait génial, et je pense, assez facile à configurer.

Il semble que les gars de Ruby l'ont fait à nouveau, et il y a exactement ce que je demande dans Ruby: http://ozmm.org/posts/fakefs.html .

Y a-t-il quelque chose de similaire à distance pour Java?

81
devoured elysium

Google a une implémentation open-source en mémoire de Java 7 FileSystemProvider. Le le projet s'appelle jimfs .


Si vous utilisez Java 6 ou version antérieure, il existe une alternative: j'ai utilisé Apache Commons VFS avant avec beaucoup de succès. Il semble être un peu comme le FileSystemProvider personnalisé un autre répondeur mentionné est dans Java 7.

Il vient préchargé avec plusieurs implémentations de système de fichiers: File, RAM, S/FTP et Jar pour n'en nommer que quelques-uns. J'ai également vu un plugin pour S .

50
Michael Deardeuff

Dans Java 6 et versions antérieures, c'est difficile car des classes comme File et FileInputStream ne fournissent aucun moyen de répartir vers différents "systèmes de fichiers virtuels" dans Java espace.

Dans Java 7, il existe un support pour les systèmes de fichiers virtuels; voir Développement d'un fournisseur de système de fichiers personnalisé . Je ne sais pas si cela vous permettra de faire ce que vous voulez faire, mais c'est un bon endroit pour commencer à chercher.


Meh. Étant donné qu'il ne semble pas y avoir de faux système de fichiers, je suppose que je vais implémenter une implémentation minimale par moi-même. Je ne gagne rien en utilisant FileSystemProvider

En fait, vous gagnez en utilisant FileSystemProvider:

  • Vous implémentez quelque chose qui (s'il est publié sous une licence open source) pourrait être très utile à d'autres personnes dans votre position et à d'autres fins.

  • Vous vous simplifiez la tâche si vous décidez de passer à un FileSystemProvider sur lequel quelqu'un d'autre pourrait travailler en ce moment.

35
Stephen C

Vous pouvez utiliser org.junit.rules.TemporaryFolder À partir du package JUnit :

La règle TemporaryFolder permet la création de fichiers et de dossiers dont la suppression est garantie à la fin de la méthode de test (qu'elle réussisse ou échoue):

Exemple:

final TemporaryFolder testFolder = new TemporaryFolder();
testFolder.create();
final Path filePath = testFolder.newFile("input.txt").toPath();
final Path dirPath = testFolder.newFolder("subfolder").toPath();

Vous pouvez également quitter la partie .toPath():

final File filePath = testFolder.newFile("input.txt");
13
thomas.mc.work

Vous pouvez abstraire l'utilisation de File en utilisant l'intention de "quelque part pour écrire des données" en modifiant votre API pour utiliser un OutputStream au lieu d'un File, puis passer l'API un FileOutputStream dans votre code de production, mais passez-le ByteArrayOutputStream à partir de vos tests. Un ByteArrayOutputStream est un flux en mémoire, il est donc très rapide et vous pouvez simplement inspecter son contenu en utilisant ses méthodes - il est parfait pour les tests. Il y a aussi les ByteArrayInputStream correspondants si vous voulez lire les données.

Les systèmes de fichiers sont généralement assez rapides - à moins que vous ne fassiez beaucoup d'E/S de fichiers dans vos tests, je ne m'embêterais pas.

Notez que la création d'un Java File objet ne pas crée un fichier sur le disque, c'est-à-dire ce qui suit le code ne provoque aucune modification sur le disque:

File f = new File("somepath"); // doesn't create a file on disk
8
Bohemian

Jimfs , de Google, est un système de fichiers NIO en mémoire, idéal pour les tests.

6
pron

Un moyen simple serait d'utiliser la manière de votre système de fournir un système de fichiers entièrement basé sur RAM - tempfs sous Linux, un disque RAM sous Windows.

4
Paŭlo Ebermann

MockFTPServer semble avoir quelques implémentations de faux système de fichiers (Unix/Windows)

Il semble que vous puissiez utiliser ces fausses implémentations de système de fichiers de manière assez séparée de tous les concepts FTP. J'essaie maintenant pour exactement les mêmes objectifs que ceux que vous avez décrits.

4
Deano

je ne suis pas sûr des cadres spécifiques, mais une approche générale en termes de OOP serait d'écrire des couches abstraites au-dessus de tout code d'accès aux fichiers (interfaces à gogo!) et peut-être une façade pour Facilitez l'utilisation des opérations courantes. Ensuite, vous vous moquez simplement d'une couche en dessous du code que vous testez actuellement et il s'agit essentiellement d'un faux système de fichiers (ou du moins le code que vous testez ne saura pas le contraire).

si vous envisagez d'utiliser un framework d'injection de dépendances pour gérer cela à votre place, cela facilitera la possibilité de changer les composants pour une implémentation fausse d'une interface. si vous suivez les modèles d'inversion de contrôle, en passant toutes les dépendances dans le constructeur de la classe que vous testez, cela facilitera également les tests.

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
   }
}

j'espère que mon Java est correct, je n'ai pas écrit Java depuis longtemps, mais vous obtiendrez, espérons-le, la dérive. j'espère que je ne sous-estime pas le problème ici et étant trop simpliste!

bien sûr, tout cela suppose que vous voulez dire de vrais tests unitaires, c'est-à-dire tester les plus petites unités de code possibles, et non un système entier. pour les tests d'intégration, une approche différente est nécessaire.

2
WickyNilliams

ShrinkWrap du projet Arquillian cherche à inclure un système de fichiers compatible NIO dans la mémoire

Vous pouvez créer un système de fichiers simple en mémoire en procédant comme suit:

FileSystem fs = ShrinkWrapFileSystems.newFileSystem(ShrinkWrap.create(GenericArchive.class))
2
Rob Oxspring

Deux autres systèmes de fichiers en mémoire pour Java are,

système de fichiers de mémoire

éphémères

Les deux implémentent l'API du système de fichiers NIO.2.

1
mostly alien

Je cherchais "Fake Java FileSystem" sur Google et j'ai trouvé cette question. Malheureusement, c'est tout ce que j'ai trouvé. J'ai donc écrit ce faux FileSystem moi-même: https://github.com/dernasherbrezon/mockfs

Je l'utilise pour simuler des IOExceptions pendant la lecture/écriture dans des fichiers. IOException pourrait se produire par exemple en raison de "l'absence d'espace disque", ce qui est presque impossible à simuler par d'autres moyens.

0
Andrey Rodionov