sebastianbergmann/phpunit · error · NoMoreParameterSetsConfiguredException

Not enough parameter sets configured, only %d parameter sets

Error message

Not enough parameter sets configured, only %d parameter sets given for %s::%s()

What it means

Thrown during test execution when a mocked method configured with withParameterSetsInOrder(...) receives more calls than you configured parameter sets for. OrderedParameterSets::apply() pops one parameter set per invocation; once the stack is empty, the next invocation raises NoMoreParameterSetsConfiguredException naming the class::method that ran out. The old withConsecutive() API of PHPUnit 9 produced the same class of failure.

Source

Thrown at src/Framework/MockObject/Runtime/Rule/OrderedParameterSets.php:61

        foreach ($stack as $parameters) {
            if (!$parameters instanceof IndexedParameters) {
                if (is_array($parameters)) {
                    $parameters = new Parameters($parameters);
                } else {
                    $parameters = new Parameters([$parameters]);
                }
            }

            $this->stack[] = $parameters;
        }

        $this->numberOfConfiguredParameterSets = count($stack);
    }

    public function apply(BaseInvocation $invocation): void
    {
        if ($this->stack === []) {
            throw new NoMoreParameterSetsConfiguredException(
                $invocation,
                $this->numberOfConfiguredParameterSets,
            );
        }

        $parameters      = array_shift($this->stack);
        $this->applied[] = $parameters;

        $parameters->apply($invocation);
    }

    /**
     * Checks if the invocation $invocation matches the current rules. If it
     * does the rule will get the invoked() method called which should check
     * if an expectation is met.
     *
     * @throws ExpectationFailedException
     */

View on GitHub (pinned to f123cdb2a2)

Solutions

  1. Identify the extra call from the exception message (it names Class::method) and the stack trace at the mocked call site.
  2. Add parameter sets for every legitimate invocation: withParameterSetsInOrder([...set1], [...set2], [...set3]).
  3. If the number of calls varies, replace the strict ordered sets with withParameterSetsInAnyOrder() plus expects($this->exactly(n)), or match arguments per-call with a willReturnCallback()/Callback constraint.
  4. Make the fixture smaller or deterministic so the call count is known and each call gets a set.
  5. If extra calls are a production bug (duplicate processing), fix the calling code instead of the test.

Example fix

// before
$queue->expects($this->any())->method('push')
    ->withParameterSetsInOrder(['a'], ['b']);
foreach (['a', 'b', 'c'] as $job) { $queue->push($job); } // third call has no set

// after: one set per expected call
$queue->expects($this->exactly(3))->method('push')
    ->withParameterSetsInOrder(['a'], ['b'], ['c']);
Defensive patterns

Strategy: try-catch

Validate before calling

// Before relying on ordered parameter sets, make the call count deterministic:
// a fixed fixture plus expects(exactly(n)) guarantees every call has a set.
$items = ['a', 'b'];
$mock->expects($this->exactly(count($items)))->method('push')
    ->withParameterSetsInOrder(['a'], ['b']);

Try / catch

// NoMoreParameterSetsConfiguredException escapes the mocked call itself;
// catch it only to convert it into a clearer failure:
use PHPUnit\Framework\MockObject\NoMoreParameterSetsConfiguredException;
try {
    $sut->import($rows);
} catch (NoMoreParameterSetsConfiguredException $e) {
    self::fail('More calls than configured parameter sets: ' . $e->getMessage());
}

Prevention

When it happens

Trigger: $mock->expects($this->any())->method('push')->withParameterSetsInOrder([1], [2]) while the code under test calls push() a third time. The exception escapes from the third $mock->push(...) call itself, so the failure points at the call site in the code under test.

Common situations: Loops or batch processors that iterate more items than the two or three parameter sets written in the test; a retry adding an extra call; an event listener invoked per entity; leftover withConsecutive() tests migrated to PHPUnit 10/11 where the new withParameterSetsInOrder() replaces it; fixtures growing without updating the configured sets.

Related errors


AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23). Data as JSON: /api/errors/22d05bc10222f27b. Report an issue: GitHub.