2010-07-11 18 views
17

Estoy intentando escribir una prueba unitaria para un controlador usando Zend y PHPUnitcómo puedo reemplazar php: // input al hacer las pruebas unitarias

En el código consigo datos de php: // input

$req = new Zend_Controller_Request_Http(); 
$data = $req->getRawBody(); 

Mi código funciona bien cuando pruebo la aplicación real, pero a menos que pueda suministrar datos como una publicación HTTP sin procesar, $ datos siempre estarán en blanco. El método getRawBody() básicamente llama a file_get_contents ('php: // input'), pero ¿cómo anulo esto para suministrar los datos de prueba a mi aplicación?

Respuesta

3

Siempre que el $req->getRawBody() es, como usted dice, lo mismo que 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(); 
No

una solución perfecta, pero similar a lo que he utilizado en el pasado en el diseño de secuencias de comandos para manejar correos electrónicos entubados con gran éxito.

+0

Yeap, no es una solución perfecta, pero ¿cómo me he decidido a poner en práctica también. Gracias. –

+0

No recomendaría esta solución, utilizando sentencias 'if' para realizar código diferente en pruebas unitarias frente a producción. Lo ideal es que su código ejecute las mismas declaraciones lógicas en ambos mundos. Ver la solución de @MitMaro a continuación, que utiliza una ruta de entrada configurable. –

7

Puede intentar burlarse del objeto en las pruebas de su unidad. Algo como esto:

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

así que esto funcionaría si estuviera pasando el objeto Zend_Controller_Request_Http al código que estaba probando, desafortunadamente el controlador maneja todo esto bajo el capó. Así que creo que la única forma de hacerlo es cambiar mi aplicación para probar el entorno en el que estoy y manejar el caso especial. –

10

Yo tenía el mismo problema y la forma en que me fijo que era tener la cadena 'php://input' como una variable que se puede programar en tiempo de ejecución. Sé que esto realmente no se aplica directamente a esta pregunta, ya que requeriría modificar el Zend Framework. Pero de todos modos puede ser útil para alguien.

Por ejemplo:

<?php 
class Foo { 

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

se convertiría en

<?php 
class Foo { 

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

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

} 

Luego, en mi unidad de prueba que puedo hacer:

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

también podría tener una propiedad protegida y cambiarla a pública mediante la reflexión en las pruebas. Entonces, para la producción, su código es un poco más limpio. (Asumiendo php 5.3) – edorian

0

Zend_Controller_Request_HttpTestCase contiene métodos para establecer y obtener varia petición HTTP/respuestas.

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

Cuestiones relacionadas