2010-11-21 11 views
8

Używam PHPUnit do moich testów jednostkowych Używam symulowanego obiektu do testowania, czy metoda jest wywoływana z poprawnymi parametrami. Działa to dobrze, gdy chcę zrobić to tylko raz.Jak mogę sprawdzić, czy ta sama metoda jest wywoływana z poprawnymi parametrami z PHPUnit i próbnym obiektem

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

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

Teraz mam sytuację, którą chcę przetestować, jeśli dziennik update jest wywoływany po raz drugi (z innymi parametrami). Nie widzę, jak mogę to zrobić za pomocą metody "z".

Czy ktoś ma sugestię?

Odpowiedz

13

Nie znam waszych szyderczych ram. Zwykle po prostu tworzysz kolejne oczekiwania. Zakładam, że powinno to również działać z tymi ramami.

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

Edit

Wydaje się, że ramy PHPUnit nie obsługuje wiele różnych oczekiwania na tej samej metody. Zgodnie z tym site musisz użyć funkcji indeksu.

To będzie wtedy wyglądać tak

$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

Używam wewnętrznych możliwości próbnych PHPUnit. Wewnątrz mojej implementacji (metoda, która jest testowana) dziennik update jest wywoływany dwa razy, więc nie mogę przetestować argumentów metody z różnymi oczekiwaniami. – Fino

+0

Według tej witryny można to osiągnąć za pomocą funkcji indeksu wywołań. http://www.kreamer.org/phpunit-cookbook/1.0/mocks/set-mock-expectations-for-multiple-calls-to-afunction – treze

+0

Dzięki! Wartość $ this-> at (index) wykonuje zadanie. Dziękuję również za link do strony internetowej, kilka użytecznych informacji. – Fino

1

poprzednią odpowiedź jest poprawna.

Odpowiedź można znaleźć w podręczniku PHPUnit: http://www.phpunit.de/manual/3.6/en/phpunit-book.html#test-doubles.mock-objects.tables.matchers szukaj dopasowań. dopasowujących są klasy zwracane przez funkcje dowolny() Nigdy() etc ... Jedno czego potrzebujesz to PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex, zwrócony przez metodę na()

można znaleźć bardziej przeglądanie klas phpunit (dodaj do ścieżki projektu i użyj IDE, takich jak netbeans, aby przeskoczyć do nich i zobaczyć, co możesz użyć)

1

Od PHPUnit 4.2 możesz użyć asercji withConsecutive. Pod warunkiem, że znasz kolejność połączeń. Twój makiety będzie wyglądać następująco:

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

returnCallback

Jeśli nie można używać withConsecutive(), prawdopodobnie dlatego, że jesteś na starej wersji PHPUnit, masz inną opcję z returnCallback.

Funkcja returnCallback jest wywoływana za każdym razem, gdy wywoływana jest metoda próbna. Oznacza to, że możesz zapisać argumenty, które są do niego przekazywane w celu późniejszej inspekcji. Na przykład:

$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); 
Powiązane problemy