2010-11-21 3 views
8

Sto usando PHPUnit per i miei test di unità Sto usando un oggetto fittizio per verificare se un metodo viene chiamato con i parametri corretti. Funziona bene quando voglio farlo una volta sola.Come posso testare se lo stesso metodo viene chiamato con parametri corretti con PHPUnit e oggetto fittizio

$logMock = $this->getMockBuilder('Logger') 
      ->disableOriginalConstructor() 
      ->getMock(); 

    //check if it updates the correct record 
    $logMock->expects($this->exactly(1)) 
      ->method('updateLog') 
      ->with(456, 'some status'); 

ora ho la situazione che voglio verificare se l'updateLog viene chiamato una seconda volta (con parametri diversi). Non vedo come posso farlo con il metodo 'with'.

Qualcuno ha un suggerimento?

risposta

13

Non conosco il tuo scherno quadro. Di solito però crei un'altra aspettativa. Presumo che dovrebbe funzionare anche con questo framework.

$logMock->expects($this->exactly(1)) 
     ->method('updateLog') 
     ->with(100, 'something else'); 

Modifica

Sembra che il quadro PHPUnit non supporta più le aspettative differenti sullo stesso metodo. In base a questo site è necessario utilizzare la funzionalità di indice.

Sarebbe quindi simile a questa

$logMock->expects($this->at(0)) 
     ->method('updateLog') 
     ->with(456, 'some status'); 
$logMock->expects($this->at(1)) 
     ->method('updateLog') 
     ->with(100, 'something else'); 
$logMock->expects($this->exactly(2)) 
     ->method('updateLog'); 
+0

Sto utilizzando le funzionalità di simulazione interna di PHPUnit. All'interno della mia implementazione (il metodo in fase di test) l'updateLog viene chiamato due volte, quindi non posso testare gli argomenti del metodo con aspettative diverse. – Fino

+0

Secondo questo sito è possibile ottenere ciò utilizzando la funzionalità dell'indice di chiamata. http://www.kreamer.org/phpunit-cookbook/1.0/mocks/set-mock-expectations-for-multiple-calls-to-a-function – treze

+0

Grazie! Il $ this-> at (index) fa il lavoro. Grazie anche per il link al sito web, alcune informazioni utili. – Fino

1

La risposta precedente è corretta.

è possibile trovare la risposta nel manuale PHPUnit http://www.phpunit.de/manual/3.6/en/phpunit-book.html#test-doubles.mock-objects.tables.matchers cercare gli abbinamenti. Matchers sono le classi restituiti dalle funzioni qualsiasi(), mai() ecc ... Quello che vi serve è il PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex, restituito dal metodo a()

è possibile trovare ulteriori naviga in classi PHPUnit (ADD al percorso del progetto e utilizzare un IDE come netbeans per saltare a loro e vedere cosa è possibile utilizzare)

1

A partire da PHPUnit 4.2, è possibile utilizzare l'asserzione withConsecutive. A condizione che tu conosca l'ordine delle chiamate. Il tuo finto sarebbe simile a questa:

$logMock->expects($this->exactly(2)) 
     ->method('updateLog') 
     ->withConsecutive(
      array(456, 'some status') 
      array(100, 'something else') 
     ); 
0

returnCallback

Se non è possibile utilizzare withConsecutive(), forse perché si sono su una vecchia versione di PHPUnit, avete un'altra opzione con returnCallback.

La funzione returnCallback viene richiamata ogni volta che viene richiamato il metodo di simulazione. Ciò significa che puoi salvare gli argomenti che gli vengono passati per un'ispezione successiva. Ad esempio:

$actualArgs = array(); 

$mockDependency->expects($this->any()) 
    ->method('setOption') 
    ->will($this->returnCallback(
     function($option, $value) use (&$actualArgs){ 
      $actualArgs[] = array($option, $value); 
     } 
    )); 

$serviceUnderTest->executeMethodUnderTest(); 

$this->assertEquals(
    array(
     array('first arg of first call', 'second arg of first call'), 
     array('first arg of second call', 'second arg of second call'), 
    ), 
    $actualArgs);