2011-04-26 14 views
15

Voglio prendere in giro un metodo nella stessa classe che sto testando.Mock un metodo nella stessa classe in fase di test

ClassA { 
    function hardToTest($arg) { 
     // difficult to test code 
    } 

    function underTest() { 
     return $this->hardToTest('foo'); 
    } 
} 

stavo pensando che potrei usare riflessione per fare questo, ma forse è solo un segno che dovrei spostare hardToTest in un altro oggetto.

+0

sto utilizzando PHPUnit 5.7, e avevo bisogno di usare 'createPartialMock' e specificare quali metodi devono essere deriso. – Ryan

+0

Concordo sul fatto che dover prendere in giro un metodo nella stessa classe in fase di test è l'odore del codice e che il metodo dovrebbe essere spostato in un'altra classe. –

risposta

15

Questo test avrà esito positivo se passa a 'foo' a hardToTest(). Questo è noto come simulazione parziale nella documentazione di PHPUnit perché stai prendendo in giro solo alcuni dei metodi.

ClassATest { 
    function testUnderTest() { 
     $mock = $this->getMock('ClassA', ['hardToTest']); 
     $mock->expects($this->once()) 
      ->method('hardToTest') 
      ->with('foo'); 
     $mock->underTest(); 
    } 
} 

Sono d'accordo con il tuo istinto che questo bisogno può essere un odore di codice che ti dice che questa classe sta facendo troppo.

PHPUnit 5.4+

Dal getMock() è stata sconsigliata a 5,4, utilizzare getMockBuilder() invece:

$mock = $this->getMockBuilder('ClassA') 
      ->setMethods(['hardToTest']) 
      ->ge‌​tMock(); 
+2

in realtà dovrebbe essere '$ mock = $ this-> getMock ('ClassA', ['hardToTest']);' secondo parametro di 'getMock' dovrebbe essere una matrice di nomi di metodi. –

+0

In alcuni casi è necessario eseguire una simulazione parziale, ad esempio, se uno dei metodi di classe esegue una richiesta HTTP. Sarebbe bene prendere in giro quel metodo e restituire uno stub per la richiesta. – b01

+0

ora che getMock è deprecato, come possiamo farlo? – julestruong

1

Qual è esattamente il motivo per cui il metodo è difficile da testare?

Se il metodo è protetto, è possibile semplicemente estendere la Classe A e rendere pubblico il numero hardToTest($arg).

La linea di fondo è che non si dovrebbe modificare la classe solo perché è necessario scrivere unittest per esso.

+1

Ho bisogno di testare un metodo che chiama un altro metodo in THE SAME CLASS. Mi piacerebbe essere in grado di prendere in giro la funzionalità per quel metodo in fase di esecuzione. Spostare il metodo in un'altra classe non è la mia opzione preferita. – james

+1

un po 'come questo: http://codepad.viper-7.com/v3SA0s –

+0

sì questo è molto vicino all'idea .... creare una sottoclasse del sistema sotto test e stub fuori i metodi rilevanti che non voglio test. grazie per l'aiuto – james

0

Ciò che ho fatto è stato creare una sottoclasse del mio sistema in prova con il metodo pertinente stoppato.

Problemi correlati