2014-03-12 15 views
5

Ich experimentiere mit vfsStream für Unit-Testing-Dateisystem Interaktionen und haben sehr schnell in eine große Hürde gerannt. Eine der Validierungsüberprüfungen des zu testenden Codes ist die Ausführung von realpath() auf einem angegebenen Eingabepfad, um zu testen, ob es sich um einen tatsächlichen Pfad und nicht um einen Unsinn handelt. Realpath schlägt jedoch immer auf einem vfstream-Pfad fehl.vfstream Pfade und realpath

Der folgende Code veranschaulicht das Problem außerhalb einer bestimmten Klasse.

$content = "It rubs the lotion on its skin or else it gets the hose again"; 
$url  = vfsStream::url ('test/text.txt'); 
file_put_contents ($url, $content); 
var_dump ($url); 
var_dump (realpath ($url)); 
var_dump (file_get_contents ($url)); 

Die Ausgabe ist wie folgt:

string(27) "vfs://FileClassMap/text.txt" 
bool(false) 
string(61) "It rubs the lotion on its skin or else it gets the hose again" 

Offensichtlich ist die vfsStream erstellt die Datei und schrieb den gegebenen Inhalt, aber ich kann nicht überprüfen, ob der Weg, um es mit realpath korrekt ist. Da Realpath innerhalb des eigentlichen Codes verwendet wird, muss ich daran arbeiten.

Ich glaube wirklich nicht, Realpath zu entfernen ist ein vernünftiger Ansatz, weil es eine wichtige Funktion innerhalb des Codes ausführt, und eine wichtige Überprüfung zu beseitigen, nur um den Code testbar scheint eine ziemlich schlechte Lösung zu sein. Ich könnte auch einen wenn um den Test setzen, um es zu Testzwecken zu deaktivieren, aber ich denke auch nicht, dass das eine gute Idee ist. Außerdem würde ich es hassen, das an jedem Punkt des Codes zu tun, an dem ich realpath() anrufen könnte. Die dritte Option wäre, eine RAM-Disk für Dateisystem-Komponententests einzurichten, aber das ist auch nicht ideal. Sie müssen nach sich selbst aufräumen (was vfsstream Ihnen helfen soll, die Notwendigkeit zu vermeiden), und wie man es tatsächlich tut, wird sich von OS zu OS unterscheiden, so dass die Komponententests aufhören würden, OS-agnostisch zu sein.

Gibt es eine Möglichkeit, einen vfstream-Pfad in einem Format zu erhalten, das tatsächlich mit realpath funktioniert?

Der Vollständigkeit halber ist das folgende Codefragment aus der Klasse, die ich tatsächlich testen möchte.

if (($fullPath = realpath ($unvalidatedPath)) 
&& (is_file ($fullPath)) 
&& (is_writable ($fullPath))) { 

A Refactoring die folgenden (als pro mögliche Lösung 2) erlaubt es mir, mit vfsStream zu testen, aber ich denke, es ist in der Produktion problematisch sein könnte:

// If we can get a canonical path then do so (realpath can fail on URLs, stream wrappers, etc) 
$fullPath = realpath ($unvalidatedPath); 
if (false === $fullPath) { 
    $fullPath = $unvalidatedPath; 
} 

if ((is_file ($fullPath)) 
&& (is_writable ($fullPath))) { 

Antwort

3

Wenn Sie Namespaces verwenden Sie außer Kraft setzen können die Realpath-Funktion nur in der Testklasse. Ich verwende immer kanonische Pfade in meinen vfsStream-Testfällen, weil ich die realpath() -Funktion selbst nicht testen möchte.

namespace my\namespace; 

/** 
* Override realpath() in current namespace for testing 
* 
* @param string $path  the file path 
* 
* @return string 
*/ 
function realpath($path) 
{ 
    return $path; 
} 

Gut hier beschrieben: http://www.schmengler-se.de/en/2011/03/php-mocking-built-in-functions-like-time-in-unit-tests/

Verwandte Themen