2010-07-21 15 views
17

Estoy intentando configurar un objeto Mock en PHPUnit para devolver valores para diferentes propiedades (que se accede mediante la función __get)PHPUnit - la creación de objetos Mock para actuar como talones de las propiedades

Ejemplo:

class OriginalObject { 
public function __get($name){ 
switch($name) 
case "ParameterA": 
    return "ValueA"; 
case "ParameterB": 
    return "ValueB"; 
} 
} 

estoy tratando de burlarse de esto usando:

$mockObject = $this->getMock("OrigionalObject"); 

$mockObject ->expects($this->once()) 
    ->method('__get') 
    ->with($this->equalTo('ParameterA')) 
    ->will($this->returnValue("ValueA")); 

$mockObject ->expects($this->once()) 
    ->method('__get') 
    ->with($this->equalTo('ParameterB')) 
    ->will($this->returnValue("ValueB")); 

pero esto falla terriblemente :-(

+1

son los errores tipográficos ("original" en lugar de "original", la falta de cotizaciones de cierre en ValorA y ValorB) en el simulacro parte del código de su código real, o errores de transcripción? – Phil

+1

LOL gracias Phil (por señalar mi dislexia) Los errores tipográficos (modificados ahora) están en el código de ejemplo - claramente este no es el código real que se está ejecutando – Tim

Respuesta

9

No he intentado burlarse __get todavía, pero tal vez esto va a funcionar:

// getMock() is deprecated 
// $mockObject = $this->getMock("OrigionalObject"); 
$mockObject = $this->createMock("OrigionalObject"); 

$mockObject->expects($this->at(0)) 
    ->method('__get') 
    ->with($this->equalTo('ParameterA')) 
    ->will($this->returnValue('ValueA')); 

$mockObject->expects($this->at(1)) 
    ->method('__get') 
    ->with($this->equalTo('ParameterB')) 
    ->will($this->returnValue('ValueB')); 

yo ya he usado $ this-> al() en una prueba y funciona (pero no es una solución óptima) . Lo obtuve de esta banda de rodamiento:

How can I get PHPUnit MockObjects to return different values based on a parameter?

+0

hey koen $ this-> at() trabaja para mí - Gracias ;-) ¿Por qué no crees que esta es una solución óptima? – Tim

+1

No es realmente escalable y la prueba es difícil de leer. Una devolución de llamada puede ser más fácil de leer si le das un buen nombre. Pero, en primer lugar, me gustaría tratar de refactorizar el __get. – koen

+0

también, está probando el estado (que algunos consideran como mala práctica) y aún más, el estado privado (que muchos consideran como una mala práctica). Por supuesto, hay personas inteligentes que no ven un problema en eso y usted puede ser uno de ellos. – koen

4

esto debería funcionar:

class Test extends \PHPUnit_Framework_TestCase { 
... 
    function testSomething() { 
     $mockObject = $this->getMock("OrigionalObject"); 

     $mockObject 
       ->expects($this->any()) 
       ->method('__get') 
       ->will($this->returnCallback('myMockGetter')); 
     ... 
    } 
... 
} 

function myMockGetter($classPropertyName) { 
    switch($classPropertyName) { 
     case 'ParameterA': 
      return 'ValueA'; 

     case 'ParameterB': 
      return 'ValueB'; 
    } 
} 
... ... 
+0

Creo que mi solución es más óptima que koen, pero él hace algunos puntos importantes en sus comentarios. Creo que una posible solución sería crear una clase de prueba y no usar un objeto de prueba. Esto se usa a menudo para cosas como adaptadores HTTP. –

Cuestiones relacionadas