Last active
April 3, 2024 07:35
-
-
Save bizley/d4bd39d0c4a1b4106c56845ff0c07068 to your computer and use it in GitHub Desktop.
PHPUnit 10 withConsecutive() replacement (idea by nicolas-grekas)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Tests\Unit; | |
use PHPUnit\Framework\Assert; | |
use PHPUnit\Framework\Constraint\Constraint; | |
class ConsecutiveCalls extends Assert | |
{ | |
/** | |
* @var array<mixed[]> | |
*/ | |
private array $data = []; | |
private int $internalCounter = -1; | |
/** | |
* @param mixed[] ...$args | |
*/ | |
private function __construct(array ...$args) | |
{ | |
foreach ($args as $arg) { | |
if (!\is_array($arg)) { | |
throw new \InvalidArgumentException('All arguments must be arrays'); | |
} | |
$this->data[] = $arg; | |
} | |
} | |
/** | |
* @param mixed[] ...$arguments | |
*/ | |
public static function withArgs(array ...$arguments): self | |
{ | |
return new self(...$arguments); | |
} | |
public function __invoke(mixed ...$args): void | |
{ | |
$testData = $this->data[++$this->internalCounter] ?? null; | |
if ($testData === null) { | |
$testData = $this->data[$this->internalCounter % \count($this->data)]; | |
} | |
foreach ($testData as $key => $value) { | |
if ($value instanceof Constraint) { | |
$value->evaluate($args[$key]); | |
} else { | |
self::assertEquals($value, $args[$key]); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Tests\Unit; | |
use PHPUnit\Framework\TestCase; | |
class BearerTest extends TestCase | |
{ | |
public function testConsecutiveArguments(): void | |
{ | |
// expects arguments: | |
// 'abc' and 8 on first call | |
// 'def' and 2 on second call | |
// will return 1 every time | |
$this->createMock(Mocked::class) | |
->expects(self::exactly(2)) | |
->method('name')->willReturnCallback( | |
ConsecutiveCalls::withArgs( | |
['abc', 8], | |
['def', 2], | |
) | |
) | |
->willReturn(1); | |
// expects arguments: | |
// 'abc' and 8 on first and on second call | |
// will return 1 on first call, and 2 on second call | |
$this->createMock(Mocked::class) | |
->expects(self::exactly(2)) | |
->method('name')->willReturnCallback( | |
ConsecutiveCalls::withArgs( | |
['abc', 8] | |
) | |
) | |
->willReturnOnConsecutiveCalls(1, 2); | |
// expects arguments: | |
// 'abc' and object fullfilling the callback | |
$this->createMock(Mocked::class) | |
->expects(self::once()) | |
->method('name')->willReturnCallback( | |
ConsecutiveCalls::withArgs( | |
['abc', self::callback( | |
static fn (Abc $arg) => $arg->getStatus() === 1 | |
)] | |
) | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment