I'm building unit tests for class Foo
, and I'm fairly new to unit testing.
A key component of my class is an instance of BarCollection
which contains a number of Bar
objects. One method in Foo
iterates through the collection and calls a couple methods on each Bar
object in the collection. I want to use stub objects to generate a series of responses for my test class. How do I make the Bar
stub class return different values as I iterate? I'm trying to do something along these lines:
$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()`
So Foo->someMethod()
will produce data based on the results it receives from the Bar
objects. But this gives me the following error whenever the array is longer than one:
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
One thought I had was to use ->will($this->returnCallback())
to invoke a callback method, but I don't know how to indicate to the callback which Bar
object is making the call (and consequently what response to give).
Another idea is to use the onConsecutiveCalls()
method, or something like it, to tell my stub to return 1 the first time, 2 the second time, etc, but I'm not sure exactly how to do this. I'm also concerned that if my class ever does anything other than ordered iteration on the collection, I won't have a way to test it.