una tipos sismo simulacros simulacro realización procedimiento primeros plan para informe incendio guia evacuacion empresa ejemplos desarrollo auxilios mocking phpunit

mocking - tipos - simulacro de incendio en una empresa



¿Creando un simulacro en phpunit sin burlarse de ningún método? (4)

Cuando estoy probando mi código php con PHPUnit, estoy tratando de encontrar la manera correcta de burlar un objeto sin burlar ninguno de sus métodos.

El problema es que si no getMockBuilder()->setMethods() , se getMockBuilder()->setMethods() todos los métodos del objeto y no podré llamar al método que quiero probar; pero si llamo a setMethods() , entonces necesito decirle qué método usar para setMethods() pero no quiero simular ningún método. Pero necesito crear el simulacro para poder evitar llamar al constructor en mi prueba.

Aquí hay un ejemplo trivial de un método que me gustaría probar:

class Foobar { public function __construct() { // stuff happens here ... } public function myMethod($s) { // I want to test this return (strlen($s) > 3); } }

Podría probar myMethod() con:

$obj = new Foobar(); $this->assertTrue($obj->myMethod(''abcd''));

Pero esto llamaría al constructor de Foobar, que no quiero. Entonces, en cambio, trataría de:

$obj = $this->getMockBuilder(''Foobar'')->disableOriginalConstructor()->getMock(); $this->assertTrue($obj->myMethod(''abcd''));

Pero llamar a getMockBuilder() sin usar setMethods() dará como resultado que se setMethods() de todos sus métodos y devuelvan el valor nulo, por lo que mi llamada a myMethod() devolverá nulo sin tocar el código que intento probar.

Mi solución hasta ahora ha sido esto:

$obj = $this->getMockBuilder(''Foobar'')->setMethods(array(''none'')) ->disableOriginalConstructor()->getMock(); $this->assertTrue($obj->myMethod(''abcd''));

Esto se burlará de un método llamado ''ninguno'', que no existe, pero a PHPUnit no le importa. Dejará myMethod () sin bloquear para que yo pueda llamarlo, y también me permitirá deshabilitar el constructor para que no lo llame. ¡Perfecto! Excepto que parece una trampa tener que especificar un nombre de método que no existe: ''ninguno'', ''blargh'' o ''xyzzy''.

¿Cuál sería la forma correcta de hacerlo?


Puede pasar null a setMethods() para evitar burlarse de cualquier método. Pasar una matriz vacía simulará todos los métodos. Este último es el valor predeterminado para los métodos que ha encontrado.

Dicho esto, diría que la necesidad de hacer esto podría señalar un defecto en el diseño de esta clase. ¿Debería este método estar estático o moverse a otra clase? Si el método no requiere una instancia completamente construida, es una señal para mí que podría ser un método de utilidad que podría estartico.


Otra solución ingeniosa pero sucinta es simplemente enumerar el constructor de magia como uno de los métodos burlados:

$mock = $this->getMock(''MyClass'', array(''__construct''));


Esto funcionó para mí:

$this->getMock($class, array(), array(), '''', false);


O simplemente puede usar getMock() directamente.

$mock = $this->getMock(''MyClass'', null, array(), null, false);