sebastianbergmann/phpunit · error · InvalidDataProviderException

Data Provider method %s::%s() is not public

Error message

Data Provider method %s::%s() is not public

What it means

Thrown while resolving a @dataProvider annotation/attribute when the referenced provider method exists but is not public. PHPUnit invokes provider methods statically from the framework, so ReflectionMethod::isPublic() is enforced and non-public providers are rejected with InvalidDataProviderException.

Source

Thrown at src/Metadata/Api/DataProvider.php:129

            try {
                $method     = new ReflectionMethod($_dataProvider->className(), $_dataProvider->methodName());
                $className  = $_dataProvider->className();
                $methodName = $_dataProvider->methodName();

                if (Test::isTestMethod($method)) {
                    Event\Facade::emitter()->testRunnerTriggeredPhpunitWarning(
                        sprintf(
                            'Method %s::%s() used by test method %s::%s() is also a test method',
                            $_dataProvider->className(),
                            $_dataProvider->methodName(),
                            $testMethod->getDeclaringClass()->getName(),
                            $testMethod->getName(),
                        ),
                    );
                }

                if (!$method->isPublic()) {
                    throw new InvalidDataProviderException(
                        sprintf(
                            'Data Provider method %s::%s() is not public',
                            $className,
                            $methodName,
                        ),
                    );
                }

                if (!$method->isStatic()) {
                    throw new InvalidDataProviderException(
                        sprintf(
                            'Data Provider method %s::%s() is not static',
                            $className,
                            $methodName,
                        ),
                    );
                }

View on GitHub (pinned to f123cdb2a2)

Solutions

  1. Change the provider method's visibility to public
  2. Keep the visibility but move the data generation into a public static provider that delegates

Example fix

// before
#[DataProvider('provideCases')]
public function testX(int $n): void { ... }

protected static function provideCases(): array { ... }

// after
#[DataProvider('provideCases')]
public function testX(int $n): void { ... }

public static function provideCases(): array { ... }
Defensive patterns

Strategy: validation

Validate before calling

$method = new ReflectionMethod($testClass, 'provideCases');

if (!$method->isPublic()) {
    // make it public before running the suite
}

Type guard

function isValidDataProvider(ReflectionMethod $method): bool
{
    return $method->isPublic()
        && $method->isStatic()
        && $method->getNumberOfParameters() === 0;
}

Prevention

When it happens

Trigger: Declaring the provider as protected or private: '#[DataProvider('provideCases')] private static function provideCases(): ...' and running the test.

Common situations: Refactoring tests and changing provider visibility to reduce the public API of test classes; copy-pasting providers from classes where they were protected utilities.

Related errors


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