2010-12-09 4 views
3

Ich schreibe einige Objekte, die das Dateisystem umfangreich nutzen. Ich bin nicht sicher, was der richtige Weg ist, sie zu testen.Testobjekt mit Dateisystemfunktionen

Ich weiß in der Theorie, ich sollte Dateisystemfunktionalität in einigen Objekten abstrahieren und sie dann verspotten, aber es wäre in meinem Fall ziemlich sinnlos: Die Hauptverwendung der Klassen, die ich testen möchte, ist die Verwaltung von Dateien. Also hätte ich beim Testen der neuen Objekte das gleiche Problem, nur eine Ebene verschoben.

Die einzige Möglichkeit, die Tests zu machen, ist, tatsächlich mit dem Dateisystem zu arbeiten. Das Problem besteht darin, dass Tests sowohl im Browser als auch in der Befehlszeile ausgeführt werden. Daher muss ich in einem Verzeichnis mit Schreibzugriff für alle arbeiten. Darüber hinaus scheint dies keine sehr tragbare Lösung zu sein.

Irgendwelche Ideen?

Antwort

5

Sie können mock the filesystem with vfsStream als suggested in the PHPUnit Manual:

vfsStream ein Stream Wrapper für ein virtuelles Dateisystem, das in Unit-Tests hilfreich sein kann das reale Dateisystem zu verspotten [...] Wenn die PEAR-Installer auf Ihrem verfügbar System, müssen Sie nur die folgenden Befehle auszuführen:

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

Es examples at Github ist und auch ein Wiki

+8

'Hah - du bist ein Müll-Dateisystem. Das letzte Dateisystem, das ich hatte, war viel besser als du, lol '. Diese Art von Spott? ;) – PaulJWilliams

+2

Die PHPUnit-Dokumentation ist unvollständig. Gibt es eine bessere Referenz? Es fehlen Informationen darüber, wie das Dateisystem gespottet werden kann (z. B. simulieren, dass eine Datei existiert, den Inhalt der simulierten Datei angeben usw.) –

+0

@dpk gibt es [Beispiele bei Github] (https://github.com/mikey179/vfsStream/ Baum/Meister/Beispiele) und auch ein [Wiki] (https://github.com/mikey179/vfsStream/wiki) – Gordon

1

Führen Sie sehr niedrige PHP-Funktionen ein, die nichts anderes tun als Dateisystemfunktionen aufzurufen und diese innerhalb Ihres Codes zu verwenden.

Dann überschreiben Sie diese Funktion in Ihrem Testkabelbaum mit Stubs (die möglicherweise aufzeichnen, dass sie aufgerufen wurden). Auf diese Weise können Sie überprüfen, ob Ihr Code im Live-System die richtigen Low-Level-PHP-Funktionen aufruft. Für einen Komponententest ist das alles, was Sie wirklich tun können.

+0

Die ursprüngliche Frage nicht Unit-Tests erwähnt, scheint dies insbesondere eine Integration im Zusammenhang Frage zu sein. Ich hätte gedacht, dass etwas verspotten würde den Zweck der Tests untergraben würde? –

1

Wie ich es sehe haben Sie drei Möglichkeiten:

  • Akzeptieren Sie, dass einige Tests besser gestellt sind als Integrationstests. Starten Sie den Test, indem Sie eine kleine Welt erstellen, in der der Test ausgeführt werden soll (in% TEMP% basierend auf dem Klassen-/Methodennamen), und vernichten Sie sie anschließend, wenn Sie fertig sind.
  • Untersuchen Sie die Abstraktionsschicht und extrahieren Sie die Datei IO aus der Klasse. Das schafft eine Schnittstelle dafür. Der Rest verwendet Integrationstests (aber dies wird sehr klein sein). Dies unterscheidet sich von oben darin, anstatt Datei zu machen. Lesen Sie die Absicht, sagen Sie ioThingie.loadSettings().
  • Mock die IO (wie von Gordon oben vorgeschlagen).

ich normalerweise mit einer Mischung aus Optionen eins und zwei gehen und drei nur für Grenzfälle benutzen, wie ich in C# finde nur die rohe IO-Schicht (System.IO.File) spöttischen wirklich zeigen Sie spöttische Aussagen schreiben können, und macht Ihren Test ein wenig zu abhängig von der Implementierung, aber die VFS oben sieht aus wie es verspottet die FS, anstatt eines der Objekte.

+0

Das Problem ist, dass meine Objekte hauptsächlich mit dem Dateisystem befassen, und es gibt nicht viel zu testen, wenn ich die Dateisystemfunktionen in den Integrationstests verschieben. – Andrea

1

Eine andere Variante ist, PHP-Funktionen zu verspotten, die Dateisystem mit runkit verwenden. Nicht sicher, es ist die beste Lösung, aber es funktioniert. Es gibt phpunit-mockfunction - PHPUnit Erweiterung, die das Spotten von PHP-Funktionen vereinfacht.

So Beispiel ist:

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... 
    } 
} 
Verwandte Themen