unitarias tutorial pruebas example descargar composer php phpunit simpletest

pruebas - phpunit tutorial



¿Equivalente a las "simulaciones parciales" de SimpleTest en PHPUnit? (3)

Estoy tratando de migrar un montón de pruebas de SimpleTest a PHPUnit y me preguntaba si hay un equivalente para las simulaciones parciales de SimpleTest.

Actualización: Parece que no puedo encontrar nada en los documentos que sugiera que esta función esté disponible, pero se me ocurrió que podría usar una subclase. ¿Es esta una buena o mala idea?

class StuffDoer { protected function doesLongRunningThing() { sleep(10); return "stuff"; } public function doStuff() { return $this->doesLongRunningThing(); } } class StuffDoerTest { protected function doesLongRunningThing() { return "test stuff"; } } class StuffDoerTestCase extends PHPUnit_Framework_TestCase { public function testStuffDoer() { $sd = new StuffDoerTest(); $result = $sd->doStuff(); $this->assertEquals($result, "test stuff"); } }


Al leer la página enlazada, un simulacro parcial SimpleTest parece ser un simulacro donde solo algunos de los métodos están anulados. Si esto es correcto, esa funcionalidad es manejada por un simulador de PHPUnit normal.

Dentro de un PHPUnit_Framework_TestCase , creas un simulacro con

$mock = $this->getMock(''Class_To_Mock'');

Lo que crea una instancia simulada donde todos los métodos no hacen nada y devuelven nulo. Si solo desea anular algunos de los métodos, el segundo parámetro para getMock es una matriz de métodos para anular.

$mock = $this->getMock(''Class_To_Mock'', array(''insert'', ''update''));

creará una instancia simulada de Class_To_Mock con las funciones de insert y update eliminadas, listas para que se especifiquen sus valores de retorno.

Esta información está en los documentos phpunit .

Tenga en cuenta que esta respuesta muestra más ejemplos de códigos actualizados, para versiones de PHPUnit que comienzan con 5.4


No creo que PHPUnit admita simulacros parciales para el sistema bajo prueba. Si está intentando aislar métodos, estoy seguro de que su implementación funciona, también lo he hecho.

Sin embargo, trato de evitar hacer esto, por un par de razones.

Primero, acopla su prueba muy fuertemente a la implementación interna de la clase. ¿Realmente te importa si un método llamado doesLongRunningThing fue llamado, o es más importante que el "LongRunningThing" haya terminado?

En segundo lugar, cuando me encuentro con esto, siempre me pregunto si tengo una clase haciendo el trabajo de dos. Un extracto de refactorización de clase podría estar en orden. Las pruebas se vuelven mucho más fáciles si doesLongRunningThing() convierte en su propia clase, incluso con un solo método.

Creo que la solución es inyectar los servicios de los que depende su SUT (http://en.wikipedia.org/wiki/Dependency_injection). Esto también hace que la implementación DoesLongRunningThing más comprobable.

Sin saltar a las interfaces, esto es lo que haría:

class DoesLongRunningThing { public function execute() { sleep(10); return "stuff"; } } class StuffDoer { protected $doesLongRunningThing; public function setLongRunningThinger(DoesLongRunningThing $obj) { $this->doesLongRunningThing = $obj; } public function doStuff() { return $this->doesLongRunningThing->execute(); } }

Ahora es fácil burlarse:

class StuffDoerTestCase extends PHPUnit_Framework_TestCase { public function testStuffDoer() { $dlrtMock = $this->getMock(''DoesLongRunningThing''); $dlrtMock->expects($this->any())->will($this->returnValue("test stuff")); $sd = new StuffDoer(); $sd->setLongRunningThinger($dlrtMock); $result = $sd->doStuff(); $this->assertEquals($result, "test stuff"); } }


PHPUnit_Framework_TestCase::getMock está en desuso desde phpunit 5.4 . Podemos usar setMethods en setMethods lugar.

Se puede llamar a setMethods (array $ methods) en el objeto Mock Builder para especificar los métodos que se reemplazarán con un doble de prueba configurable. El comportamiento de los otros métodos no se cambia. Si llama a setMethods (null), no se reemplazará ningún método.

https://phpunit.de/manual/current/en/test-doubles.html

$observer = $this->getMockBuilder(Observer::class) ->setMethods([''update'']) ->getMock();

Tenga en cuenta que el getMock anterior es PHPUnit_Framework_MockObject_MockBuilder::getMock . (phpunit5.6)