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
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'));
}
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.
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).
+1 per "Test di integrazione come effetto collaterale". Mi piace. – GordonM