php mocking tdd phpunit

PHPUnit: ¿cómo me burlo de múltiples llamadas de método con múltiples argumentos?



mocking tdd (4)

En caso de que alguien encuentre esto sin mirar la sección correspondiente en la documentación de phpunit, puede usar el método withConsecutive

$mock->expects($this->exactly(3)) ->method(''MyMockedMethod'') ->withConsecutive( [$arg1, $arg2, $arg3....$argNb], [arg1b, $arg2b, $arg3b....$argNb], [$arg1c, $arg2c, $arg3c....$argNc] ... );

El único inconveniente de esto es que el código DEBE llamar a MyMockedMethod en el orden de los argumentos proporcionados. Todavía no he encontrado una manera de evitar esto.

Estoy escribiendo una prueba de unidad para un método usando PHPUnit. El método que estoy probando realiza una llamada al mismo método en el mismo objeto 3 veces pero con diferentes conjuntos de argumentos. Mi pregunta es similar a las preguntas hechas here y here

Las preguntas formuladas en las otras publicaciones tienen que ver con métodos de burla que solo toman un argumento.

Sin embargo, mi método toma múltiples argumentos y necesito algo como esto:

$mock->expects($this->exactly(3)) ->method(''MyMockedMethod'') ->with($this->logicalOr($this->equalTo($arg1, $arg2, arg3....argNb), $this->equalTo($arg1b, $arg2b, arg3b....argNb), $this->equalTo($arg1c, $arg2c, arg3c....argNc) ))

Este código no funciona porque equalTo() valida solo un argumento. Dándole más de un argumento lanza una excepción:

El argumento # 2 de PHPUnit_Framework_Constraint_IsEqual :: __ construct () debe ser un número

¿Hay una manera de hacer una burla logicalOr para un método con más de un argumento?

Gracias por adelantado.


En mi caso la respuesta resultó ser bastante simple:

$this->expects($this->at(0)) ->method(''write'') ->with(/* first set of params */); $this->expects($this->at(1)) ->method(''write'') ->with(/* second set of params */);

La clave es usar $this->at(n) , siendo n la novena llamada del método. No pude hacer nada con ninguna de las variantes logicalOr() que probé.


Para otros que buscan coincidir con los parámetros de entrada y proporcionar valores de retorno para llamadas múltiples ... esto funciona para mí:

$mock->method(''myMockedMethod'') ->withConsecutive([$argA1, $argA2], [$argB1, $argB2], [$argC1, $argC2]) ->willReturnOnConsecutiveCalls($retValue1, $retValue2, $retValue3);


Detectar una llamada de método para devolver el valor de un mapa

$map = array( array(''arg1_1'', ''arg2_1'', ''arg3_1'', ''return_1''), array(''arg1_2'', ''arg2_2'', ''arg3_2'', ''return_2''), array(''arg1_3'', ''arg2_3'', ''arg3_3'', ''return_3''), ); $mock->expects($this->exactly(3)) ->method(''MyMockedMethod'') ->will($this->returnValueMap($map));

O puedes usar

$mock->expects($this->exactly(3)) ->method(''MyMockedMethod'') ->will($this->onConsecutiveCalls(''return_1'', ''return_2'', ''return_3''));

Si no necesita especificar argumentos de entrada