2011-04-29 4 views
39

Chcę nazwać moją wyśmiewaną metodę dwukrotnie różnymi oczekiwanymi argumentami. To nie działa, ponieważ expects($this->once()) zawiedzie podczas drugiego połączenia.W PHPUnit, jak wskazać różne z() na kolejne wywołania do wyśmiewane metody?

$mock->expects($this->once()) 
    ->method('foo') 
    ->with('someValue'); 

$mock->expects($this->once()) 
    ->method('foo') 
    ->with('anotherValue'); 

$mock->foo('someValue'); 
$mock->foo('anotherValue'); 

Próbowałem również:

$mock->expects($this->exactly(2)) 
    ->method('foo') 
    ->with('someValue'); 

Ale jak mogę dodać z(), aby dopasować drugie połączenie?

+2

Dlaczego musisz dopasować argumenty? Nie można użyć metody onConsecutiveCalls(), aby powiedzieć "za pierwszym razem, zwraca to, po raz drugi zwraca"? Użyłbyś dokładnie (2) i onConsecutiveCalls() – fiunchinho

+2

to samo [pytanie] (http://stackoverflow.com/questions/5484602/mock-in-phpunit-multiple-configuration-of-the-same-method-with -different-argume) z powiązanego bloku. – meze

+2

Możliwy duplikat [phpunit mock method multiple calls with different arguments] (https://stackoverflow.com/questions/5988616/phpunit-mock-method-multiple-calls- with-different-arguments) –

Odpowiedz

51

Trzeba użyć at():

$mock->expects($this->at(0)) 
    ->method('foo') 
    ->with('someValue'); 

$mock->expects($this->at(1)) 
    ->method('foo') 
    ->with('anotherValue'); 

$mock->foo('someValue'); 
$mock->foo('anotherValue'); 

Należy pamiętać, że indeksy przeszły do ​​at() zastosowanie we wszystkich metoda zwraca do tej samej makiety obiektu. Jeśli drugie wywołanie metody było bar(), nie zmieniłbyś argumentu na at().

7

Odwoływanie się od the answer from a similar question,

Od PHPUnit 4.1 można użyć withConsecutive np.

$mock->expects($this->exactly(2)) 
    ->method('set') 
    ->withConsecutive(
     [$this->equalTo('foo'), $this->greaterThan(0)], 
     [$this->equalTo('bar'), $this->greaterThan(0)] 
     ); 

Jeśli chcesz, aby powrócić na kolejnych połączeń:

$mock->method('set') 
     ->withConsecutive([$argA1, $argA2], [$argB1], [$argC1, $argC2]) 
     ->willReturnOnConsecutiveCalls($retValueA, $retValueB, $retValueC); 

To nie jest idealny do wykorzystania at() jeśli można uniknąć dlatego as their docs claim

Parametr $ wskaźnik dla at() matcher odnosi się do indeksu rozpoczynającego się od zera we wszystkich wywołaniach metod dla danego obiektu próbnego. Należy zachować ostrożność podczas korzystania z tego modułu dopasowującego, ponieważ może to doprowadzić do powstania kruchych testów, które są zbyt ściśle powiązane z konkretnymi szczegółami implementacji.

+0

Tak, to jest naprawdę głupie rozwiązanie w phpunit. Każdy jest wprowadzany w błąd przez ten fakt, np. Https://addshore.com/2015/08/misled-by-phpunit-at-method/ – forsberg

Powiązane problemy