unitarias que pruebas example ejecutar descargar php unit-testing phpunit

que - pruebas unitarias php



¿Cómo se usa PHPUnit para probar una función si se supone que esa función matará a PHP? (5)

Básicamente, tengo un método de una clase llamada killProgram, que está destinado a enviar un redireccionamiento hTTP y luego matar a PHP.

¿Cómo se supone que voy a probar esto? Cuando ejecuto phpunit, no devuelve nada para esa prueba y se cierra por completo.

En este momento estoy considerando hacer que la función killProgram arroje una excepción que no debería manejarse, lo que me permitiría afirmar que se lanzó una excepción.

¿Hay una mejor manera?


Como todas las pruebas son ejecutadas por el mismo proceso de PHPUnit, si utilizas exit / die en tu código PHP, matarás todo, como habrás notado ^^

Entonces, debes encontrar otra solución, sí, como regresar en lugar de morir; o lanzando una excepción (puede probar si algún código probado arrojó una excepción esperada) .

Tal vez PHPUnit 3.4 y su --process-isolation (consulte Opcionalmente, ejecute cada prueba usando un proceso separado de PHP ) podría ayudar (al no tener todo lo que muere) , pero aún así no podría obtener el resultado de la prueba, si PHPUnit no recupera el control.

He tenido este problema un par de veces; lo resolvió regresando en lugar de morir, incluso regresando varias veces, si es necesario, para volver "lo suficientemente alto" en la pila de llamadas ^^
Al final, supongo que ya no tengo ningún "dado" en mi aplicación ... Probablemente sea mejor, al pensar en MVC, por cierto.


Esto se relaciona con una serie de problemas que he tenido para obtener algún código heredado para pasar una prueba. Así que he creado una clase Testable como esta ...

class Testable { static function exitphp() { if (defined(''UNIT_TESTING'')) { throw new TestingPhpExitException(); } else { exit(); } } }

Ahora simplemente reemplazo las llamadas a exit () con Testable :: exitphp ().

Si está bajo prueba, solo defino UNIT_TESTING, en producción no lo hago. Parece un simple simulacro.


Me doy cuenta de que ya has aceptado una respuesta para esto y es una vieja pregunta, pero creo que esto podría ser útil para alguien, así que aquí va:

En lugar de usar die() , podría usar throw new RuntimeException() (o una clase de excepción propia), que también detendrá la ejecución del programa (aunque de una manera diferente) y use setExpectedException() PHPUnit para atraparlo. Si desea que su secuencia de comandos die() cuando se encuentra esa excepción, imprimiendo absolutamente nada a nivel del usuario, eche un vistazo a set_exception_handler() .

Específicamente, estoy pensando en un escenario en el que colocarías el set_exception_handler() -call en un archivo bootstrap que las pruebas no usan, por lo que el controlador no se activará allí independientemente del escenario, por lo que nada interfiere con PHPUnit. manejo de excepciones nativas.


No es necesario cambiar el código solo para poder probarlo, simplemente puede usar set_exit_overload() (provisto por test_helpers del mismo autor que PHPUnit).


Obviamente es una vieja pregunta, pero mi sugerencia sería mover el código que die() en un método diferente que luego puede simular.

Como un ejemplo, en lugar de tener esto:

class SomeClass { public function do() { exit(1); // or die(''Message''); } }

hacer esto:

class SomeClass { public function do() { $this->terminate(123); // or $this->terminate(''Message''); } protected function terminate($code = 0) { exit($code); } // or protected function terminate($message = '''') { die($message); } }

De esta forma, puede simular fácilmente el método de terminate y no tiene que preocuparse de que el script finalice sin que pueda atraparlo.

Su prueba se vería así:

class SomeClassTest extends /PHPUnit_Framework_TestCase { /** * @expectedExceptionCode 123 */ public function testDoFail() { $mock = $this->getMock(''SomeClass''); $mock->expects($this->any()) ->method(''terminate'') ->will($this->returnCallback(function($code) { throw new /Exception($code); })); // run to fail $mock->do(); } }

No he probado el código, pero debería estar bastante cerca de un estado de trabajo.