8 years after the question asked, 5 years after it was first answered I had the same question and came to a similar conclusion. This is what I did, which is basically the same as the second part of David's accepted answer, except I'm using a later version of PHPUnit.
Basically you can mock the ArrayAccess
interface methods. Just need to remember that you probably want to mock both offsetGet
and offsetExists
(you should always check an array key exists before you use it otherwise you could encounter an E_NOTICE
error and unpredictable behaviour in your code if it doesn't exist).
$thingyWithArrayAccess = $this->createMock(ThingyWithArrayAccess::class);
$thingyWithArrayAccess->method('offsetGet')
->with('your-offset-here')
->willReturn('test-value-1');
$thingyWithArrayAccess->method('offsetExists')
->with($'your-offset-here')
->willReturn(true);
Of course, you could have a real array in the test to work with, like
$theArray = [
'your-offset-here-1' => 'your-mock-value-for-offset-1',
];
$thingyWithArrayAccess = $this->createMock(ThingyWithArrayAccess::class);
$thingyWithArrayAccess->method('offsetGet')
->willReturnCallback(
function ($offset) use ($theArray) {
return $theArray[$offset];
}
);
$thingyWithArrayAccess->method('offsetExists')
->willReturnCallback(
function ($offset) use ($theArray) {
return array_key_exists($offset, $theArray);
}
);