2010-11-21 4 views
8

J'utilise PHPUnit pour mes tests unitaires J'utilise un objet simulé pour tester si une méthode est appelée avec les paramètres corrects. Cela fonctionne bien quand je veux juste faire une fois.Comment puis-je tester si la même méthode est appelée avec les paramètres corrects avec PHPUnit et objet mock

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

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

Maintenant, j'ai la situation que je veux tester si le updateLog est appelé une seconde fois (avec des paramètres différents). Je ne vois pas comment je peux le faire avec la méthode 'avec'.

Est-ce que quelqu'un a une suggestion?

Répondre

13

Je ne connais pas votre cadre de moquerie. Habituellement, vous créez simplement une autre attente. Je suppose que cela devrait également fonctionner avec ce cadre.

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

Modifier

Il semble que le cadre de PHPUnit ne supporte pas les multiples attentes différentes sur la même méthode. Selon ce site vous devez utiliser la fonctionnalité d'index.

Il serait alors ressembler à ceci

$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

J'utilise les fonctionnalités de simulation interne de PHPUnit. A l'intérieur de mon implémentation (la méthode en cours de test), updateLog est appelé deux fois, donc je ne peux pas tester les arguments de méthode avec des attentes différentes. – Fino

+0

Selon ce site, vous pouvez y parvenir en utilisant la fonctionnalité d'indexation des appels. http://www.kreamer.org/phpunit-cookbook/1.0/mocks/set-mock-expectations-for-multiple-calls-to-a-function – treze

+0

Merci! Le $ this-> at (index) fait le travail. Merci également pour le lien vers le site, quelques informations utiles. – Fino

1

La réponse précédente est correcte. Vous pouvez trouver la réponse dans le manuel PHPUnit http://www.phpunit.de/manual/3.6/en/phpunit-book.html#test-doubles.mock-objects.tables.matchers Matchers sont les classes retournées par les fonctions (tout), jamais() etc ... Le dont vous avez besoin est le PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex, retourné par la méthode à()

vous pouvez trouver plus en naviguant sur les classes PHPUnit (ajouter au chemin du projet et utilisez un IDE comme netbeans pour y accéder et voir ce que vous pouvez utiliser)

1

Depuis PHPUnit 4.2, vous pouvez utiliser l'assertion withConsecutive. Pourvu que vous connaissiez l'ordre des appels. Votre maquette ressemblerait à ceci:

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

returnCallback

Si vous ne pouvez pas utiliser withConsecutive(), peut-être parce que vous êtes sur une ancienne version de PHPUnit, vous avez une autre option avec returnCallback.

La fonction returnCallback est invoquée chaque fois que votre méthode Fock est appelée. Cela signifie que vous pouvez enregistrer les arguments qui lui sont transmis pour une inspection ultérieure. Par exemple:

$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); 
Questions connexes