2011-09-20 13 views
5

Ho bisogno di creare un autoloader per la mia applicazione. Non voglio dipendere da un file nel filesystem, quindi come faccio a prendere in giro una nuova chiamata? O come collaudi una classe di autoloader? Grazie.PHPUnit - test autoloader class

risposta

1

Creare alcuni file di classe specifici per testare il caricatore automatico e inserirli in una directory separata (di pari livello del test) che è possibile registrare con il caricatore automatico. Utilizzare class_exists($class, false) per verificare se una classe viene caricata senza richiamare il caricatore automatico.

Nota: È utile progettare il caricatore automatico in modo non statico in modo da poter creare un'istanza separata per il test anziché testarne uno attivo.

Qui ci sono i test per il metodo autoload() del mio caricatore automatico personalizzato come un esempio:

function test_autoload_loadsExistingClass() { 
    $this->fixture->registerPrefix('TestClasses', self::$root . 'models'); 
    if (class_exists('TestClasses_Autoloader_Foo', false)) { 
     self::error('Class TestClasses_Autoloader_Foo is already loaded'); 
    } 
    $this->fixture->autoload('TestClasses_Autoloader_Foo'); 
    if (!class_exists('TestClasses_Autoloader_Foo', false)) { 
     self::fail('Class TestClasses_Autoloader_Foo failed to load'); 
    } 
} 

function test_autoload_silentlyIgnoresMissingClasses() { 
    $this->fixture->registerPrefix('Foo', self::$root . 'models'); 
    $this->fixture->autoload('Foo_Bar'); 
} 

function test_autoload_searchesIncludePathForUnknownPrefix() { 
    if (class_exists('TestClasses_Autoloader_Foo', false)) { 
     self::error('Class TestClasses_Autoloader_Foo is already loaded'); 
    } 
    set_include_path(self::$root . 'include' . PATH_SEPARATOR . self::$savedIncludePath); 
    $this->fixture->autoload('TestClasses_Autoloader_Foo'); 
    if (!class_exists('TestClasses_Autoloader_Foo', false)) { 
     self::fail('Class TestClasses_Autoloader_Foo failed to load'); 
    } 
} 

Aggiornamento: Wow, non so come ho perso "Non voglio dipendere da un file nel filesystem "nella tua domanda, ma questa è una bella chiave. Dovrai effettuare la chiamata a include nel proprio metodo del caricatore automatico (ad esempio includeFile($path)). Questo ti permetterà di prendere in giro il metodo durante il test in modo da non coinvolgere i file sul disco. Oltre a testare la classe come faresti normalmente: alimenta gli input (come sopra) delle classi da caricare automaticamente e convalidare che la classe chiami includeFile() con i percorsi corretti quando dovrebbe.

function testAutoloadLoadsExistingClass() { 
    $fixture = $this->getMock('MyAutoloader', 
      array('includeFile'), // mock the call to `include` 
      array(...));   // constructor args 
    $fixture->expects($this->once()) 
      ->method('includeFile') 
      ->with('My/Package/Class') 
      ->will($this->returnValue(true)); 
    self::assertTrue($fixture->autoload('My_Package_Class')); 
} 
4

O come si fa a testare una classe autoloader

Imho non c'è bisogno di unità di testare il caricatore automatico a tutti.

Se si esegue il bootstrap dell'applicazione si bloccherà molto perché si riesce a trovare tutte le classi necessarie o il caricatore automatico funziona correttamente.

Ogni singolo test nella vostra suite di test verificherà che il caricatore automatico sia in grado di caricare la "classe sottoposta a test", quindi non mi preoccuperei molto del test dell'unità.

Forse lo si chiama "test di integrazione come effetto collaterale" se si desidera, ma direi che è abbastanza buono.

Se non si ritiene che ciò sia sufficiente, inserire l'istruzione require/include in una funzione protetta e sovrascrivere quella funzione in un autoloader di test e controllare se riceve i valori corretti.

+1

+1 per "Test di integrazione come effetto collaterale". Mi piace. – GordonM

0

come si esegue il test di una classe di caricatore automatico?

Dipende da cosa fa la classe del caricatore automatico. Ad esempio, è possibile verificare se la registrazione del callback autoload ha funzionato con spl_autoload_register.

O se il caricatore automatico fornisce una funzione LoadLibrary che carica tutte le classi e le interfacce della libreria, per verificare se tutte le classi sono state caricate. Ma questo normalmente dipendeva dal file system (che credo sia ok).