Estoy tratando de probar una clase de mapeador con PHPUnit. Me puedo burlar fácilmente de la instancia de PDO que se inyectará en la clase de correlacionador, pero no puedo imaginarme cómo simular la clase PreparedStatement, ya que está generada por la clase PDO.PHPUnit - Cómo simular la declaración preparada de PDO
En mi caso he extendido la clase DOP, así que tengo esto:
public function __construct($dsn, $user, $pass, $driverOptions)
{
//...
parent::__construct($dsn, $user, $pass, $driverOptions);
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS,
array('Core_Db_Driver_PDOStatement', array($this)));
}
El punto es que Core_Db_Driver_PDOStatement no se inyecta en el constructor de la clase PDO, es instanciado estáticamente. E incluso si hago esto:
public function __construct($dsn, $user, $pass, $driverOptions, $stmtClass = 'Core_Db_Driver_PDOStatement')
{
//...
parent::__construct($dsn, $user, $pass, $driverOptions);
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS,
array($stmtClass, array($this)));
}
... sigue siendo un instanciation estática ya que no puedo pasar mi propia instancia de la clase imitó declaración preparada.
¿Alguna idea?
Editar: solución, adaptada de la anwser:
/**
* @codeCoverageIgnore
*/
private function getDbStub($result)
{
$STMTstub = $this->getMock('PDOStatement');
$STMTstub->expects($this->any())
->method('fetchAll')
->will($this->returnValue($result));
$PDOstub = $this->getMock('mockPDO');
$PDOstub->expects($this->any())
->method('prepare')
->will($this->returnValue($STMTstub));
return $PDOstub;
}
public function testGetFooById()
{
$arrResult = array(...);
$PDOstub = $this->getDbStub($arrResult);
}
Exactamente, que se encontró la parte que no entendía demasiado bien: no hay necesidad de inyectar la Declaración cuando se puede falso que fetchAll volverá algo que se puede decidir en la prueba. He editado mi pregunta para colocar mi solución adaptada. Gracias ! – FMaz008
El problema con este enfoque es que expone la implementación del código de la aplicación a la prueba. ¿Debería la prueba saber si la aplicación llama a -> fetch() o fetchAll()? ¡De ningún modo! Si el código está adaptado para usar fetch() en lugar de fetchaAll(), el método aún puede funcionar correctamente pero la prueba fallará. –
@TomB, este es un problema general con las dependencias de burla, no solo con esta respuesta. – PeerBr