2015-05-08 33 views
12

Avendo alcuni problemi con PHPUnit per testare i miei controller.

codice su cui stavo lavorando finora è stata implementando $_POST o di altre variabili di richiesta:

$_SERVER['REQUEST_METHOD'] = 'POST'; 
$_POST = array(
    'test' => true 
); 

La maggior parte dei test ha funzionato perfettamente in questo modo fino a quando mi imbatto in metodi che accettano impieghi di filter_input_array funzione:

$_SERVER['REQUEST_METHOD'] = 'POST'; 
$_REQUEST = $_POST = $GLOBALS['_POST'] = array(
    'test' => true 
); 

// .... 

var_dump(filter_input_array(INPUT_POST)); 

NULL

Non sono disposto a rimuovere le funzioni filter_input da codice non mio, ma non riesco a farle funzionare nei test.

Versionings:
PHP 5.5.9-1ubuntu4.9 (CLI) (costruiti 17 aprile 2015 11:44:57)
Apache/2.4.7 (Ubuntu)
PHPUnit 4.6.6 by Sebastian Bergmann e collaboratori.

Qualsiasi aiuto sarà apprezzato.

EDIT 2015.05.11

Impostazione $_SERVER con CONTENT_LENGTH e CONTENT_TYPE non risolve il problema. La mia versione di PHP non mi permette di scrivere su php://stdin come descritto in PHP 5.6.0 chagelog (o come ho capito io), ma il file_put_contents(STDIN,..) riesce ma non funziona comunque.

Poiché si tratta di un test PHPUnit, forse c'è qualche tipo di annotazione o phpunit.xml entrata non lo so ancora, che potrebbe risolvere il problema in maniera php-cgi POST setting.

+0

I suoi due esempi assegnano '$ _POST' in modo diverso. Quali sono i valori delle tre variabili '$ _REQUEST',' $ _POST' e '$ GLOBALS ['_ POST']' * prima * si fa '$ _REQUEST = $ _POST = $ GLOBALS ['_ POST']'? –

+0

I loro array vuoti. Poiché si tratta di un test phpunit, viene eseguito in linea di comando (php-cli), quindi non funziona nemmeno sul server web e non devono essere impostati i varsetti '$ _REQUEST'. Stavo guardando i test unitari del php stesso, come testano 'filter_input_array' ma non mi ha aiutato affatto. – yergo

+0

dai un'occhiata a http://stackoverflow.com/questions/5655284/how-to-pass-parameters-from-command-line-to-post-in-php-script può essere d'aiuto? – exussum

risposta

9

Se l'ingresso di filter_input_array può essere impostata solo dalla richiesta iniziale, e non ha cambiato in fase di esecuzione, allora l'unico modo per testare ancora è di avere un proxy il test di base ad un altro script di test di fare Richiesta HTTP con i dati POST giusti ed elaborazione della risposta.

main_test.php:

<?php 
$data = array(
    'testname' => 'yourtestname', 
    'some_post_var' => 'some_value' 
); 

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, "http://localhost/proxy_test.php"); 
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 

$response = curl_exec($ch); 

curl_close($ch); 

if ($response == 'pass') { 
    // test passed 
} 

proxy_test.php

<?php 
$test_name $_POST['testname']; // what test to run? 
$response = run_test($test_name); // run test that uses filter_input_array 
if ($response) { 
    echo "pass"; // used by main_test.php to check if test passed 
} else { 
    echo "fail"; 
} 
+0

Pollice in alto per suggerire "arricciatura". È una soluzione, ma sembra funzionare. Inoltre, puoi modificare il tuo proxy_test ('$ test_name =')? –

+0

Sembra un modo per farlo. Proverò. Sfortunatamente probabilmente non fornirò la copertura del codice nella configurazione che ho attualmente, ma per ora posso vivere senza quello. – yergo

5

Sembra che questa è una limitazione di PHP, filter_input_array() non consente un array $_POST modificato in fase di esecuzione. Vedi this bug per ulteriori informazioni. La soluzione è probabilmente quella di utilizzare uno di the other filter functions e passare l'array $_POST da soli.

+0

Sembra che il bug di providen esista ancora, poiché la funzione restituisce NULL invece di un array falso o vuoto. Comunque, penso che potrebbe essere possibile eseguire questo test in phpunit, in quanto questo strumento fornisce script in esecuzione in processi separati e ho fornito una risposta SO che dimostra che l'impostazione di POST all'avvio dello script è possibile. Non ho trovato una soluzione alternativa per il mio caso. – yergo

1

Se nessuno degli argomenti è impostato, questa funzione restituisce NULL, not an array of NULL values.

// No POST Le variabili di trova in richiesta

$_POST = array(); 
$args = array('some_post_var' => FILTER_VALIDATE_INT); 
$myinputs = filter_input_array(INPUT_POST, $args); 
var_dump($myinputs); 

Expected Output: array(1) { ["some_post_var"]=> NULL } 

uscita effettiva: NULL

Mentre filtrando gli array di input, fai attenzione a quali flag hai impostato oltre a FILTER_REQUIRE_ARRAY. Ad esempio, impostando le bandiere in questo modo:

<?php 
    $filter = array( 
    'myInputArr' => array('filter' => FILTER_SANITIZE_STRING, 
          'flags' => array('FILTER_FLAG_STRIP_LOW', 'FILTER_REQUIRE_ARRAY')) 
    ); 

$form_inputs = filter_input_array(INPUT_POST, $filter); 
?> 

.. si tradurrà in un vuoto $ form_inputs [ 'myInputArr'] indipendentemente da ciò che $ _POST [ 'myInputArr'] contiene.

+1

Scusa se non posso seguire, ma come mi sta aiutando con la mia domanda? – yergo