Estoy tratando de enviar una matriz precalculada de casos de prueba a un simulacro para que se devuelva en llamadas consecutivas, similar a la función de mapa. Sin embargo, toma una lista de argumentos, no una matriz.
Mi matriz ya está generada por un generador de dispositivos y puede tener una longitud variable.
Lo que quiero hacer es algo como esto, pero por supuesto esto hace que devuelva la matriz completa en la primera llamada.
// In a test case: $processorMock ->method('process') ->willReturnOnConsecutiveCalls( $fixtureLoader->getProcessorScenarios() // how to explode this? ); // class FixtureLoader pseudocode: function getProcessorScenarios(){ return [ [ $param1, $param2, $param3 ], // case 1 [ $param1, $param2, $param3 ], // case 2 ... [ $param1, $param2, $param3 ], // case N ]; }Quiero desestructurar la matriz devuelta del cargador de accesorios, usando list() o alguna construcción de lenguaje explosivo de var-args como "..." en otros idiomas, pero no pude encontrar nada nativo que funcionara.
Tengo lo que se siente como un método hacky, que publicaré como una respuesta inicial al estilo de preguntas y respuestas. Quiero saber si es el mejor método.
Un amigo sugirió una alternativa disponible en PHP 5.6 : el operador "splat" o puntos suspensivos (...) aunque no parece tener un nombre oficial en PHP, pero es una forma de desestructuración como el operador "spread" en Javascript ES6.
Si bien no he probado esto (ya que mi aplicación actualmente está bloqueada en PHP 5.4 debido a restricciones ambientales), debería funcionar simplemente así:
$processorMock ->method('process') ->willReturnOnConsecutiveCalls( ...$fixtureLoader->getProcessorScenarios() );Esta es definitivamente la alternativa más dulce que estaba buscando.
El enfoque que encontré funciona es usar la función call_user_func_array para expandir la matriz en parámetros.
call_user_func_array( [$processorMock->method('process'), 'willReturnOnConsecutiveCalls'], $fixtureLoader->getProcessorScenarios());Esto se siente desagradable y rompe la definición fluida de la simulación. Supongo que tendrá desventajas como la fragilidad para el futuro.
¡Me gustaría encontrar una alternativa más dulce antes de que se convierta en la solución de plantilla de copiar y pegar!
Actualizar:
Desde entonces, descubrí que necesito envolver algunos de los parámetros en afirmaciones, ya que son tipos más complejos, por ejemplo, clases.
// class FixtureLoader pseudocode: function getProcessorScenarios(){ $param1 = PHPUnit_Framework_Assert::IsInstanceOf('MyApp\Model\Thingumy'); $param1 = PHPUnit_Framework_Assert::isInstanceOf('MyApp\Model\Whatsit'); return [ [ $param1, $param2c1, $param3 ], // case 1 [ $param1, $param2c2, $param3 ], // case 2 ... [ $param1, $param2c3, $param3 ], // case N ]; }No es necesario usar willReturnOnConsecutiveCalls para obtener el resultado que desea.
El @dataProvider tomará una serie de datos de prueba y los introducirá en su prueba un lote a la vez, tantas veces como sea necesario para obtener los datos.
No tenía 100% claro si tiene una cantidad variable de pruebas o una cantidad variable de parámetros.
Ejemplo para 3 variables:
/** * @dataProvider getProcessorScenarios */ function testcase($param1, $param2, $param3) { // use the variables } function getProcessorScenarios() { return [ [ $param1, $param2, $param3 ], // case 1 [ $param1, $param2, $param3 ], // case 2 ... [ $param1, $param2, $param3 ], // case N ]; }Una forma de hacer esto con un número variable de variables sería pasar las variables como una matriz a la función de prueba en lugar de individualmente, pero no sé cómo podría usarlas si no sabe cuántas vienen. , así que no creo que esta sea una solución válida.
Ejemplo con cambio de número de variables:
/** * @dataProvider getProcessorScenarios */ function testcase($params) { // use the variables which are in an array } function getProcessorScenarios() { return [ [ 'params' => [$param1, $param2, $param3 ]], // case 1 [ 'params' => [$param1, $param2, $param3 ]], // case 2 ... [ 'params' => [$param1, $param2, $param3 ]], // case N ]; }