Existe-t-il des bibliothèques ou des méthodes pour simuler le système de fichiers en C # pour écrire des tests unitaires? Dans mon cas actuel, j'ai des méthodes qui vérifient si certains fichiers existent et lisent la date de création. J'aurai peut-être besoin de plus que cela à l'avenir.
c#
unit-testing
mocking
pupeno
la source
la source
Réponses:
Edit: installez le package NuGet
System.IO.Abstractions
.Ce package n'existait pas lorsque cette réponse a été acceptée à l'origine. La réponse originale est fournie pour le contexte historique ci-dessous:
la source
Cette bibliothèque imaginaire existe maintenant, il existe un package NuGet pour System.IO.Abstractions , qui fait abstraction de l'espace de noms System.IO.
Il existe également un ensemble d'aide au test, System.IO.Abstractions.TestingHelpers qui - au moment de la rédaction - n'est que partiellement implémenté, mais constitue un très bon point de départ.
la source
Vous allez probablement devoir créer un contrat pour définir les éléments dont vous avez besoin dans le système de fichiers, puis écrire un wrapper autour de ces fonctionnalités. À ce stade, vous pourrez vous moquer ou supprimer la mise en œuvre.
Exemple:
la source
Ma recommandation est d'utiliser http://systemwrapper.codeplex.com/ car il fournit des wrappers pour les types les plus utilisés dans l'espace de noms System
la source
J'ai rencontré les solutions suivantes à cela:
Je finis par utiliser toutes les méthodes ci-dessus, en fonction de ce que j'écris. Mais la plupart du temps, je finis par penser que l'abstraction est fausse lorsque j'écris des tests unitaires qui touchent l'IO.
la source
En utilisant System.IO.Abstractions et System.IO.Abstractions.TestingHelpers comme ça:
Dans votre classe de test, vous utilisez MockFileSystem () pour simuler un fichier et vous instanciez ManageFile comme:
la source
Vous pouvez le faire en utilisant Microsoft Fakes sans avoir besoin de modifier votre base de code, par exemple, car elle était déjà gelée.
Générez d' abord un faux assembly pour System.dll - ou tout autre package, puis simulez les retours attendus comme dans:
la source
Il serait difficile de se moquer du système de fichiers dans un test car les API de fichier .NET ne sont pas vraiment basées sur des interfaces ou des classes extensibles qui pourraient être simulées.
Cependant, si vous disposez de votre propre couche fonctionnelle pour accéder au système de fichiers, vous pouvez vous en moquer lors d'un test unitaire.
Au lieu de vous moquer, envisagez simplement de créer les dossiers et fichiers dont vous avez besoin dans le cadre de votre configuration de test et de les supprimer dans votre méthode de démontage.
la source
Je ne sais pas comment vous feriez une maquette du système de fichiers. Ce que vous pouvez faire est d'écrire une configuration de montage de test qui crée un dossier, etc. avec la structure nécessaire pour les tests. Une méthode de démontage le nettoierait après l'exécution des tests.
Édité pour ajouter: En y réfléchissant un peu plus, je ne pense pas que vous vouliez vous moquer du système de fichiers pour tester ce type de méthodes. Si vous vous moquez du système de fichiers pour renvoyer true si un certain fichier existe et que vous l'utilisez dans votre test d'une méthode qui vérifie si ce fichier existe, alors vous ne testez pas grand-chose. Il serait utile de se moquer du système de fichiers si vous vouliez tester une méthode qui dépendait du système de fichiers mais que l'activité du système de fichiers ne faisait pas partie intégrante de la méthode testée.
la source
Pour répondre à votre question spécifique: Non, il n'y a pas de bibliothèques qui vous permettront de simuler des appels d'E / S de fichiers (que je connaisse). Cela signifie que le test unitaire "correctement" de vos types exigera que vous preniez en compte cette restriction lorsque vous définissez vos types.
Note d'accompagnement rapide sur la façon dont je définis un test unitaire «approprié». Je pense que les tests unitaires devraient confirmer que vous obtenez le résultat attendu (qu'il s'agisse d'une exception, d'un appel à une méthode, etc.) à condition que les entrées connues soient fournies. Cela vous permet de configurer vos conditions de test unitaire comme un ensemble d'entrées et / ou d'états d'entrée. Le meilleur moyen que j'ai trouvé pour ce faire est d'utiliser des services basés sur l'interface et l'injection de dépendances afin que chaque responsabilité externe à un type soit fournie via une interface transmise via un constructeur ou une propriété.
Alors, dans cet esprit, revenons à votre question. Je me suis moqué des appels de système de fichiers en créant une
IFileSystemService
interface avec uneFileSystemService
implémentation qui n'est qu'une façade sur les méthodes du système de fichiers mscorlib. Mon code utilise alorsIFileSystemService
les types plutôt que les types mscorlib. Cela me permet de brancher mon standardFileSystemService
lorsque l'application est en cours d'exécution ou de simuler leIFileSystemService
dans mes tests unitaires. Le code de l'application est le même quelle que soit la façon dont il est exécuté, mais l'infrastructure sous-jacente permet à ce code d'être facilement testé.Je reconnais qu'il est difficile d'utiliser le wrapper autour des objets du système de fichiers mscorlib mais, dans ces scénarios spécifiques, cela vaut le travail supplémentaire car les tests deviennent tellement plus faciles et plus fiables.
la source
Créer une interface et s'en moquer pour la tester est la manière la plus propre de procéder. Cependant, comme alternative, vous pouvez jeter un œil au framework Microsoft Moles .
la source
La solution courante consiste à utiliser une API abstraite de système de fichiers (comme Apache Commons VFS pour Java): toute la logique d'application utilise l'API et le test unitaire est capable de simuler un système de fichiers réel avec une implémentation de stub (émulation en mémoire ou quelque chose comme ça).
Pour C #, l'API similaire existe: NI.Vfs qui est très similaire à Apache VFS V1. Il contient des implémentations par défaut pour le système de fichiers local et le système de fichiers en mémoire (le dernier peut être utilisé dans les tests unitaires à partir de la boîte).
la source
Nous utilisons actuellement un moteur de données propriétaire et son API n'est pas exposée en tant qu'interfaces, de sorte que nous pouvons difficilement tester notre code d'accès aux données. Ensuite, je suis allé avec l'approche de Matt et Joseph aussi.
la source
J'irais avec la réponse de Jamie Ide. N'essayez pas de vous moquer des choses que vous n'avez pas écrites. Il y aura toutes sortes de dépendances que vous ne connaissiez pas - classes scellées, méthodes non virtuelles, etc.
Une autre approche consisterait à envelopper les méthodes appropriées avec quelque chose de moquable. Par exemple, créez une classe appelée FileWrapper qui permet d'accéder aux méthodes File mais que vous pouvez simuler.
la source