PHP’s SplQueue does not include a clear() or reset() function to wipe data out of the data structure. My application requires that functionality. This leaves two options:
A) Create a subclass of SplQueue. Example:
class UserQueue extends SplQueue
{
public function clear() {
//dequeue everything
}
}
The problem with this approach is that I can’t see a way to test consumers of this subclass without relying on clear() as defined in the subclass. In essence I can’t think of a way to stub that functionality in PHPUnit short of just depending on UserQueue’s own tests.
B) Implement the clear() function in every consumer of SplQueue that requires it (most consumers in my application), which seems obviously terrible but would appear to be the only testable method.
I am hoping someone out there can tell me there is an obvious way to test option A that I’ve missed. I also considered wrapping SplQueue but I don’t see how this improves matters. Or I could monkey patch it with runkit, but a nearly-allergic aversion to runkit has been beaten into me.
After batting this around with other people on my team for a few days, the best (only) solution for a purist TDD environment that we could come up with is to inject the data structure as a mock object, stub the clear/reset function, and provide it with a closure to run as a result. Fortunately PHP and PHPUnit support this. It’s not an incredible solution, but it works.
PHPUnit Example:
$userQueueMock = $this->getMockBuilder('ProjectNamespaceUserQueue')
->setMethods(array('clear'))->getMock();
$userQueueMock->expects($this->once())->method('clear')
->return($this->returnCallback(function() { foreach($this->queue as $entry){}});
Hope this helps someone else!