2010-07-21 8 views
17

Sto cercando di configurare un oggetto Mock in PHPUnit per restituire i valori per diverse proprietà (a cui si accede usando la funzione __get)PHPUnit - creazione di oggetti Mock di agire come stub per immobili

Esempio:

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

sto cercando di prendere in giro questo utilizzando:

$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")); 

ma questo non riesce terribilmente :-(

+1

Sono errori di battitura ("originale" invece di "Originale", mancano le quotazioni di chiusura a valoreA e valoreB) nel finto codice parte del tuo codice reale, o errori di trascrizione? – Phil

+1

LOL ringrazia Phil (per indicare la mia dislessia) Gli errori di battitura (modificati ora) sono solo nel codice di esempio - chiaramente questo non è il codice in esecuzione – Tim

risposta

9

Non ho provato beffardo __get ancora, ma forse questo funzionerà:

// 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')); 

ho già usato $ this-> a() in un test e funziona (ma non è una soluzione ottimale) . Ho preso da questo battistrada:

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

+0

hey koen $ this-> at() funziona per me - Grazie ;-) Perché non pensi che questa sia una soluzione ottimale? – Tim

+1

Non è veramente scalabile e il test è difficile da leggere. Un callback può essere più facile da leggere se gli dai un buon nome. Ma in primo luogo guarderei cercando di ridefinire il __get. – koen

+0

inoltre, stai testando lo stato (che alcuni considerano come cattiva pratica) e ancora di più, lo stato privato (che molti considerano una cattiva pratica). Naturalmente ci sono persone intelligenti che non vedono un problema in questo e tu potresti essere uno di loro. – koen

4

questo dovrebbe funzionare:

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

Penso che la mia soluzione sia più ottimale di Koen, ma fa alcuni punti importanti nei suoi commenti. Penso che una possibile soluzione sarebbe quella di creare una classe di test e non utilizzare un oggetto fittizio. Questo è spesso usato per cose come gli adattatori HTTP. –

Problemi correlati