2010-12-09 85 views
3

J'écris certains objets qui font un usage intensif du système de fichiers. Je ne suis pas sûr de la bonne façon de les tester. Je sais en théorie que je devrais faire abstraction de la fonctionnalité du système de fichiers dans certains objets et ensuite me moquer d'eux, mais ce serait tout à fait inutile dans mon cas: l'utilisation principale des classes que je veux tester est de gérer les fichiers. Donc, je aurais le même problème lors du test des nouveaux objets, juste décalé d'un niveau.Objet de test avec fonctions de système de fichiers

La seule façon que je peux penser pour faire les tests est de travailler réellement avec le système de fichiers. Le problème est que les tests seront exécutés à la fois dans le navigateur et sur la ligne de commande, et j'ai donc besoin de travailler dans un répertoire avec un accès en écriture pour tout le monde. De plus, cela ne semble pas être une solution très portable.

Des idées?

Répondre

5

Vous pouvez mock the filesystem with vfsStream comme suggested in the PHPUnit Manual:

vfsStream est une enveloppe de flux pour un système de fichiers virtuel qui peut être utile dans les tests unitaires pour se moquer du système de fichiers réel [...] Si le programme d'installation de PEAR est disponible sur votre système, il vous suffit d'exécuter les commandes suivantes:

$ pear channel-discover pear.bovigo.org 
$ pear install bovigo/vfsStream-beta 

Il est examples at Github et aussi un Wiki

+8

'Hah - vous êtes un système de fichiers d'ordures. Le dernier système de fichiers que j'avais était bien meilleur que toi, lol '. Ce genre de moquerie? ;) – PaulJWilliams

+2

La documentation PHPUnit est incomplète. Y a-t-il une meilleure référence? Il manque des informations sur la façon de se moquer du système de fichiers (comme pour simuler qu'un fichier existe, spécifier le contenu du fichier simulé, etc.) –

+0

@dpk il y a [exemples sur Github] (https://github.com/mikey179/vfsStream/ tree/master/examples) et aussi un [Wiki] (https://github.com/mikey179/vfsStream/wiki) – Gordon

1

Introduisez des fonctions php de très bas niveau qui ne font rien d'autre que les fonctions du système de fichiers d'appel, et utilisez-les dans votre code. Puis, dans votre faisceau de test, remplacez cette fonction par des stubs (qui enregistrent éventuellement qu'ils ont été appelés). De cette façon, vous pouvez vérifier que votre code, dans le système live, appellera les bonnes fonctions PHP de bas niveau. Pour un test unitaire c'est tout ce que vous pouvez faire, vraiment.

+0

La question initiale ne mentionne pas les tests unitaires, cela semble être spécifiquement une question liée à l'intégration. J'aurais pensé que se moquer de quelque chose nuirait à l'objectif des tests? –

1

Comme je vois que vous avez trois possibilités:

  • que certains tests Accepter sont mieux que les tests d'intégration. Commencez le test en créant un petit monde pour que le test s'exécute (en% TEMP%, basé sur le nom de la classe/méthode), puis détruisez-le lorsque vous avez terminé.
  • Examinez votre couche d'abstraction et extrayez le fichier IO de la classe. Le créer une interface pour cela. Les autres utilisent des tests d'intégration (mais ce sera très petit). Cela diffère de ci-dessus en ce que au lieu de faire le fichier.Lisez-vous écrire l'intention, disons ioThingie.loadSettings().
  • Mock the IO (comme suggéré par Gordon ci-dessus).

je vais normalement avec un mélange d'options un et deux et trois pour utiliser uniquement les cas de pointe que je trouve en C# se moquant de la couche IO brute (System.IO.File) vraiment seulement montre que vous pouvez écrire des déclarations moqueurs, et rend votre test un peu trop dépendant de l'implémentation, cependant le vfs ci-dessus ressemble à un FS, plutôt qu'à un objet.

+0

Le problème est que mes objets traitent principalement le système de fichiers, et il n'y a pas grand chose à tester si je déplace les fonctions du système de fichiers dans les tests d'intégration. – Andrea

1

Une autre variante consiste à se moquer des fonctions PHP qui utilisent le système de fichiers avec runkit. Je ne suis pas sûr que ce soit la meilleure solution, mais cela fonctionne. Il y a phpunit-mockfunction - extension PHPUnit qui simplifie les fonctions PHP.

Ainsi par exemple est:

class Tests extends PHPUnit_Framework_TestCase { 
    // ... setUp, tearDown, other tests... 

    function test_1(){ 
     $file_size_to_return = 10; 

     $fake_filesize = new PHPUnit_Extensions_MockFunction('filesize', $this->obj->tested_method); 
     $fake_filesize->expects($this->once())->will($this->returnValue($file_size_to_return)); 

     $this->obj->tested_method(); // actually run method we want test that contains filesize() function... 
    } 
}