Skip to content

Instantly share code, notes, and snippets.

@thorsten
Created May 27, 2025 16:10
Show Gist options
  • Save thorsten/df336af33819e889f9868ba9382bb9e5 to your computer and use it in GitHub Desktop.
Save thorsten/df336af33819e889f9868ba9382bb9e5 to your computer and use it in GitHub Desktop.
PHPUnit 12 has removed deprecated methods like willReturnCallback() and changed how some mock behaviors are defined. Here’s how to rewrite your PHPUnit 12 test code in a compatible way:
✅ Original snippet (pre PHPUnit 12)
$redis = $this->createMock(RedisClient::class);
$redis->expects($this->exactly(3))
->method('callAsync')
->willReturnOnConsecutiveCalls(
resolve(['{}']),
$this->returnCallback(function (string $command, string $name, string $json) {
$this->assertEquals('ZREM', $command);
return resolve(1);
}),
resolve(0)
);
✅ Updated for PHPUnit 12
Since returnCallback() is removed, you need to use ReturnCallback from PHPUnit’s newer stubbing system:
use PHPUnit\Framework\MockObject\Stub\ReturnCallback;
$redis = $this->createMock(RedisClient::class);
$stub = new ReturnCallback(function () {
// You can vary return values based on the call count
static $calls = 0;
$calls++;
if ($calls === 1) {
return resolve(['{}']);
}
if ($calls === 2) {
// You can't use $this directly in a static function,
// so extract assertions outside or inject via closure
return resolve(1); // maybe add custom checks elsewhere
}
return resolve(0);
});
$redis->expects($this->exactly(3))
->method('callAsync')
->will($stub);
🔁 Alternative with injected $this
If you need assertions inside the callback, you can capture $this:
$self = $this;
$redis = $this->createMock(RedisClient::class);
$redis->expects($this->exactly(3))
->method('callAsync')
->will(new ReturnCallback(function (...$args) use ($self) {
static $i = 0;
$i++;
if ($i === 1) {
return resolve(['{}']);
}
if ($i === 2) {
[$command, $name, $json] = $args;
$self->assertEquals('ZREM', $command);
return resolve(1);
}
return resolve(0);
}));
✅ Summary of changes for PHPUnit 12:
Feature Old New (PHPUnit 10+)
Callback return $this->returnCallback() new ReturnCallback()
Consecutive calls willReturnOnConsecutiveCalls() Use logic inside ReturnCallback
Assertions inside stub Inline Capture $this via closure
Would you like help refactoring your test to avoid mocks altogether or to test async logic more robustly?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment