PHPUnit - multiple stubs of same class PHPUnit - multiple stubs of same class php php

PHPUnit - multiple stubs of same class


I'm unfortunately not sure if you can solve your actual question using getMock(), but my experience with getMock() itself is slim.

Only thing I can think of offhand, but not knowing your Bar class, this may not help: The third parameter of getMock() lets you pass constructor arguments (as an array).

I'd create my own mock class extending Bar as a test helper (fancy name for 'just another class that so happens to be used only in tests') that does exactly what I like and inject a series of them into your Foo object. That gives you all the control you'd want, since you can outright replace the methods in question, which getMock() does not do. Of course that also means you're not testing the Bar class in this test, which may not be what you want - though I'd recommend writing a separate test class per tested class anyway, but there are cases where that's unnecessarily purist.

$stubs = array();foreach ($array as $value) {    $stubs[] = new MyBarTestHelper($value);}

That aside, I'm honestly surprised you're only seeing the exception described when you have more than one array element. I've observed that PHPUnit actually expects you to declare any method you want it to be able to track as a getMock() parameter, and will stolidly error out otherwise, since essentially what it does internally is create its own extension of the class, wrapping each method that you expressly declare with logic that lets it determine whether it was called (= adding the method name into a logical list).

So colour me naive (seriously, I probably am, I'm a test newbie, myself), but see if this helps you any:

$stubs = array();foreach ($array as $value) {    $barStub = $this->getMock('Bar', array('GetValue'));    $barStub->expects($this->any())            ->method('GetValue')            ->will($this->returnValue($value));    $stubs[] = $barStub;}


This should satisfy the requirement to return a series of values in order as it's called if you're comfortable with the use of global. It has no idea which Bar is called but if each Bar is called by Foo once in order then it shouldn't be too hard to populate the test data.

$barTestData = array('empty',1,2,3,4,5,6);function barDataCallback(){    global $barTestData;    return next($barTestData);}


I noticed you have an extra parenthesis after "->method('GetValue')" in your code. Don't know if you copied and pasted that or not.