Estoy compilando pruebas de unidad para la clase Foo
, y soy bastante nuevo en las pruebas unitarias.PHPUnit: varios stubs de la misma clase
Un componente clave de mi clase es una instancia de BarCollection
que contiene un número de objetos Bar
. Un método en Foo
itera a través de la colección y llama a un par de métodos en cada objeto Bar
en la colección. Quiero usar objetos de código auxiliar para generar una serie de respuestas para mi clase de prueba. ¿Cómo hago para que la clase de stub Bar
devuelva diferentes valores a medida que itero? Estoy tratando de hacer algo en este sentido:
$stubs = array();
foreach ($array as $value) {
$barStub = $this->getMock('Bar');
$barStub->expects($this->any())
->method('GetValue')
->will($this->returnValue($value));
$stubs[] = $barStub;
}
// populate stubs into `Foo`
// assert results from `Foo->someMethod()`
Así Foo->someMethod()
producirá datos en base a los resultados que recibe de los objetos Bar
. Pero esto me da el siguiente error cada vez que la matriz es más que una:
There was 1 failure:
1) testMyTest(FooTest) with data set #2 (array(0.5, 0.5))
Expectation failed for method name is equal to <string:GetValue> when invoked zero or more times.
Mocked method does not exist.
/usr/share/php/PHPUnit/Framework/MockObject/Mock.php(193) : eval()'d code:25
Un pensamiento que tenía era utilizar ->will($this->returnCallback())
para invocar un método de devolución de llamada, pero no sé cómo indicar a la devolución de llamada, que Bar
objeto está haciendo la llamada (y, en consecuencia, qué respuesta dar).
Otra idea es utilizar el método onConsecutiveCalls()
, o algo así, para decirle a mi stub que regrese 1 la primera vez, 2 la segunda vez, etc., pero no estoy seguro de cómo hacerlo. También me preocupa que si mi clase hace algo diferente a la iteración ordenada en la colección, no tendré una manera de probarlo.
Crear mi propia clase de prueba era básicamente lo que tenía que hacer. En mi caso, pude usar la clase 'Bar' en sí, ya que los métodos que utilicé fueron simples getters, pero una clase simulada hecha a mano funcionaría con métodos más complejos. – keithjgrant
Con respecto a la matriz de métodos válidos pasados como el segundo parámetro a 'getMock()': Según la documentación, puede omitir este parámetro y se permitirá cualquier llamada al método. – keithjgrant
Esa fue mi comprensión intuitiva, también, pero en realidad obtuve errores omitiendo que no mencioné expresamente los métodos llamados (por supuesto, solo en combinación con '-> espera()'); por lo tanto, mencionarlo. Sin embargo, lo que observé podría ser un error de versión muy específico de la versión. Pero, de cualquier forma, estoy muy contento de que hayas hecho que tu prueba funcione como se desea. :) – pinkgothic