2011-04-29 15 views
39

Quiero llamar a mi método simulado dos veces con diferentes argumentos esperados. Esto no funciona porque expects($this->once()) fallará en la segunda llamada.En PHPUnit, ¿cómo indico diferente con() en llamadas sucesivas a un método burlado?

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

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

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

También he intentado:

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

Pero ¿Cómo se añaden a con() para que coincida con la segunda llamada?

+2

¿Por qué necesita hacer coincidir los argumentos? ¿No podría usar onConsecutive Calls() para decir "la primera vez, lo devuelve, la segunda vez lo devuelve"? Utilizaría exactamente (2) y onConsecutiveCalls() – fiunchinho

+2

la misma [pregunta] (http://stackoverflow.com/questions/5484602/mock-in-phpunit-multiple-configuration-of-the-same-method-with -different-argume) del bloque relacionado. – meze

+2

Posible duplicado de [método falso de phpunit llamadas múltiples con diferentes argumentos] (https://stackoverflow.com/questions/5988616/phpunit-mock-method-multiple-calls-with-different-arguments) –

Respuesta

51

Es necesario utilizar 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'); 

Tenga en cuenta que los índices pasaron a at() se aplican en todos método llama a un mismo objeto de burla. Si la llamada al segundo método fue a bar(), no cambiaría el argumento a at().

7

referencia a partir de the answer from a similar question,

Desde PHPUnit 4.1 se puede utilizar por ejemplo withConsecutive.

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

Si quiere hacerlo volver en llamadas consecutivas:

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

No es ideal para usar at() si se puede evitar porque as their docs claim

El parámetro de índice $ para el at() matcher se refiere al índice, comenzando en cero, en todas las invocaciones de métodos para un objeto simulado dado. Tenga cuidado al usar este matcher ya que puede llevar a pruebas frágiles que están demasiado ligadas a detalles de implementación específicos.

+0

Sí, es realmente un estúpido solución en phpunit. Todo el mundo se deja engañar por este hecho, por ejemplo, https://addshore.com/2015/08/misled-by-phpunit-at-method/ – forsberg

Cuestiones relacionadas