2010-07-11 3 views
17

Sto cercando di scrivere uno unit test per un controller utilizzando Zend e PHPUnitcome faccio a ignorare php: // input quando fare test di unità

Nel codice ottengo i dati da php: // ingresso

Il mio codice funziona correttamente quando eseguo il test dell'applicazione reale, ma a meno che non sia possibile fornire dati come post http non elaborato, $ i dati saranno sempre vuoti. Il metodo getRawBody() fondamentalmente chiama file_get_contents ('php: // input'), ma come faccio a sovrascriverlo per fornire i dati di test alla mia applicazione.

risposta

3

A condizione che il $req->getRawBody() è, come dici tu, lo stesso che file_get_contents('php://input') ...

$test = true; /* Set to TRUE when using Unit Tests */ 

$req = new Zend_Controller_Request_Http(); 
if($test) 
    $data = file_get_contents('testfile.txt'); 
else 
    $data = $req->getRawBody(); 
Non

una soluzione perfetta, ma simile a quello che ho usato in passato quando si progettano gli script per gestire le email con convogliato grande successo.

+0

Yeap, non una soluzione perfetta, ma come ho deciso di implementarlo anche. Grazie. –

+0

Non consiglierei questa soluzione - usando le istruzioni 'if' per eseguire codice diverso nei test unitari rispetto alla produzione. Preferisci che il tuo codice esegua le stesse istruzioni logiche in entrambi i mondi. Vedi la soluzione @ MitMaro sotto la quale utilizza un percorso di input configurabile. –

7

Si può provare a deridere l'oggetto nei test dell'unità. Qualcosa di simile a questo:

$req = $this->getMock('Zend_Controller_Request_Http', array('getRawBody')); 
$req->method('getRawBody') 
    ->will($this->returnValue('raw_post_data_to_return')); 
+0

quindi funzionerebbe se passassi l'oggetto Zend_Controller_Request_Http nel codice che stavo testando, sfortunatamente il controller gestisce tutto questo sotto il cofano. Quindi penso che l'unico modo per farlo sia cambiare la mia applicazione per testare l'ambiente in cui mi trovo e gestire il caso speciale. –

10

Ho avuto lo stesso problema e il modo in cui ho fissato era di avere la stringa 'php://input' come una variabile che può essere impostato in fase di esecuzione. So che questo non si applica direttamente a questa domanda in quanto richiederebbe la modifica di Zend Framework. Ma allo stesso modo può essere utile a qualcuno.

Ad esempio:

<?php 
class Foo { 

    public function read() { 
     return file_get_contents('php://input'); 
    } 
} 

sarebbe diventato

<?php 
class Foo { 

    public $_fileIn = 'php://input'; 

    public function read() { 
     return file_get_contents($this->_fileIn); 
    } 

} 

Poi nel mio test di unità che posso fare:

<?php 
$obj = new Foo(); 
$obj->_fileIn = 'my_input_data.dat'; 
assertTrue('foo=bar', $obj->read()); 
+2

potresti anche avere una proprietà protetta e cambiarla in pubblico usando la riflessione nei test. Quindi per la produzione il tuo codice è un po 'più pulito. (Supponendo php 5.3) – edorian

0

Zend_Controller_Request_HttpTestCase contiene metodi per impostare e ottenere vari richiesta http/risposte.

Ad esempio: $req = new Zend_Controller_Request_HttpTestCase; $req->setCookie('cookie', 'TRUE'); $test = $this->controller->cookieAction($req); $this->assertSame($test, TRUE);