Skip to content

Instantly share code, notes, and snippets.

@ziadoz
Last active August 4, 2023 10:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ziadoz/370fe63e24f31fd1eb989e7477b9a472 to your computer and use it in GitHub Desktop.
Save ziadoz/370fe63e24f31fd1eb989e7477b9a472 to your computer and use it in GitHub Desktop.
PHPUnit 10 - Replacement for deprecated withConsecutive() method
<?php
// @see: https://github.com/sebastianbergmann/phpunit/issues/4026
// Use `$this->with(...$this->consecutiveParams($args1, $args2))` instead of `$this->withConsecutive($args1, $args2)`.
use PHPUnit\Framework\TestCase;
class FooTest extends TestCase
{
use ConsecutiveParams;
public function testAdd(): void
{
$mock = $this->getMockBuilder(Adder::class)
->getMock();
$mock->expects($this->exactly(3))
->method('add')
->with(...$this->consecutiveParams(
[1, 1],
[2, 2],
[3, 3],
));
$mock->add(1, 1);
$mock->add(2, 2);
$mock->add(3, 3);
}
}
class Adder {
public function add(int $a, int $b): int
{
return $a + $b;
}
};
trait ConsecutiveParams {
// @see: https://stackoverflow.com/questions/75389000/replace-phpunit-method-withconsecutive
// @see: https://stackoverflow.com/questions/21861825/quick-way-to-find-the-largest-array-in-a-multidimensional-array
public function consecutiveParams(array ...$args): array
{
$callbacks = [];
$count = count(max($args));
for ($index = 0; $index < $count; $index++) {
$returns = [];
foreach ($args as $arg) {
if (! array_is_list($arg)) {
throw new \InvalidArgumentException('Every array must be a list');
}
if (! isset($arg[$index])) {
throw new \InvalidArgumentException(sprintf('Every array must contain %d parameters', $count));
}
$returns[] = $arg[$index];
}
$callbacks[] = $this->callback(new class ($returns) {
public function __construct(protected array $returns)
{
}
public function __invoke(mixed $actual): bool
{
if (count($this->returns) === 0) {
return true;
}
return $actual === array_shift($this->returns);
}
});
}
return $callbacks;
}
}
@ctrl-f5
Copy link

ctrl-f5 commented Jun 27, 2023

I have added this to the __invoke of the anon class to support arguments which are themselves phpunit Constraints:

use use PHPUnit\Framework\Constraint\Constraint;
// ...
                public function __invoke(mixed $actual): bool
                {
                    if (count($this->returns) === 0) {
                        return true;
                    }

                    $next = array_shift($this->returns);
                    if ($next instanceof Constraint) {
                        $next->evaluate($actual);
                        return true;
                    }

                    return $actual === $next;
                }

@ctrl-f5
Copy link

ctrl-f5 commented Jun 27, 2023

I also changed the $arg[$index] check to support null

                if (!array_key_exists($index, $arg)) {
                    throw new \InvalidArgumentException(sprintf('Every array must contain %d parameters', $count));
                }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment