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?
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 .
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.
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");
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
Jimfs , de Google, est un système de fichiers NIO en mémoire, idéal pour les tests.
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.
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.
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.
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))
Deux autres systèmes de fichiers en mémoire pour Java are,
système de fichiers de mémoire
Les deux implémentent l'API du système de fichiers NIO.2.
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.