2010-04-16 4 views
1

Ceci est probablement fou.Passer des classes système en tant que paramètres constructeurs

Je veux pousser l'idée de l'injection de dépendance à l'extrême. J'ai isolé tous les comportements liés à System.IO dans une seule classe afin que je puisse se moquer de cette classe dans mes autres classes et ainsi soulager ma plus grande suite de tests unitaires du fardeau de s'inquiéter du système de fichiers réel. Mais le fichier IO de classe I ne peut être testé qu'avec des tests d'intégration, ce qui - bien sûr - introduit une complexité que je ne veux pas vraiment traiter lorsque tout ce que je veux vraiment faire est de m'assurer La classe FileIO appelle les éléments System.IO corrects. Je n'ai pas besoin de tester l'intégration System.IO. Ma classe FileIO fait plus que simplement encapsuler des fonctions System.IO, de temps en temps elle contient de la logique (peut-être est-ce le problème?).

Donc ce que je voudrais, c'est pouvoir tester ma classe d'E/S de fichiers pour m'assurer qu'elle fait les bons appels système en se moquant des classes System.IO elles-mêmes. Idéalement, ce serait aussi facile que d'avoir un constructeur comme ceci:

public FileIO(
     System.IO.Directory directory, 
     System.IO.File file, 
     System.IO.FileStream fileStream 
    ) 
    { 
     this.Directory = directory; 
     this.File = file; 
     this.FileStream = fileStream; 
    } 

Et puis faire appel à des méthodes telles que:

public GetFilesInFolder(string folderPath) 
    { 
     return this.Directory.GetFiles(folderPath) 
    } 

Mais cela ne vole pas puisque les classes System.IO en question sont statiques Des classes. Autant que je sache, ils ne peuvent être instanciés de cette manière ou sous-classés dans le but de se moquer.

Répondre

5

Créez une classe qui contient des fonctions qui redirigent simplement vers System.IO. Faire une autre classe qui simule/se moque de System.IO. Ces deux classes implémentent une interface commune. Ensuite, vous n'avez pas à vous soucier du fait que System.IO est plein de statique.

1

Chaque fois que vous voulez vous protéger des éléments internes du framework que vous ne voulez pas dans votre conception, écrivez simplement une interface idéale comme vous le souhaitez. C'est-à-dire, si vous avez seulement besoin de File.Exists(), File.Delete() et File.OpenRead() alors écrivez une interface simpliste qui a seulement ces méthodes dont vous avez réellement besoin. Après cela, vous écrivez une classe wrapper autour de l'implémentation du framework qui implémente votre interface et cache avec succès la structure du framework que vous essayez d'échapper. Je l'ai fait sur le projet sans point avec la plupart des choses HttpContext qui sont accessibles via des variables statiques. Vous pouvez voir un exemple ici:

http://github.com/dotless/dotless/blob/master/src/dotless.Core/Abstractions/IResponse.cs

IResponse est mon interface simpliste qui fait exactement ce que je besoin de le faire. Le code à l'intérieur de CssResponse peut être testé à travers des tests d'intégration, mais pour l'instant je suppose que ça fonctionne car je ne l'ai jamais touché et c'est assez simple. Chaque fois que j'ai besoin de tester une classe en utilisant l'interface IResponse, j'injecte simplement un faux objet ou un faux.

salutations Daniel

Questions connexes