{"record":{"id":"d825d6cf4ad12941","repo":"sebastianbergmann/phpunit","slug":"passing-an-argument-of-type-generator-for-the-s-p","errorCode":null,"errorMessage":"Passing an argument of type Generator for the %s parameter is not supported","messagePattern":"Passing an argument of type Generator for the (.+?) parameter is not supported","errorType":"exception","errorClass":"PHPUnit\\Framework\\GeneratorNotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Framework/Assert.php","lineNumber":992,"sourceCode":"                TraversableContainsOnly::forClassOrInterface($className),\n            ),\n            $message,\n        );\n    }\n\n    /**\n     * Asserts the number of elements of an array, Countable or Traversable.\n     *\n     * @param Countable|iterable<mixed> $haystack\n     *\n     * @throws Exception\n     * @throws ExpectationFailedException\n     * @throws GeneratorNotSupportedException\n     */\n    final public static function assertCount(int $expectedCount, Countable|iterable $haystack, string $message = ''): void\n    {\n        if ($haystack instanceof Generator) {\n            throw GeneratorNotSupportedException::fromParameterName('$haystack');\n        }\n\n        self::assertThat(\n            $haystack,\n            new Count($expectedCount),\n            $message,\n        );\n    }\n\n    /**\n     * Asserts the number of elements of an array, Countable or Traversable.\n     *\n     * @param Countable|iterable<mixed> $haystack\n     *\n     * @throws Exception\n     * @throws ExpectationFailedException\n     * @throws GeneratorNotSupportedException\n     */","sourceCodeStart":974,"sourceCodeEnd":1010,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Framework/Assert.php#L974-L1010","documentation":"Assert::assertCount(int $expectedCount, Countable|iterable $haystack) explicitly rejects Generator arguments with GeneratorNotSupportedException. Counting a generator consumes it, and its count is not available without iteration, so PHPUnit fails fast instead of producing a misleading or destructive assertion. The message names the parameter that received the generator ($haystack).","triggerScenarios":"Calling $this->assertCount(3, $generator) where $generator is any \\Generator — for example the return value of a generator function invoked once, or iterable/implode-style lazy pipelines fed directly into the assertion.","commonSituations":"Refactoring production code from returning arrays to yielding generators (lazy loading, large datasets) while tests still count results; passing a collection API that yields; generators consumed twice accidentally — the guard also prevents the silent 'already been iterated' bugs.","solutions":["Materialize before counting: $this->assertCount(3, iterator_to_array($generator))","Or count via iteration: $this->assertSame(3, iterator_count($generator)) — remember this consumes the generator","Keep the generator in a variable and assert on the array form: $items = iterator_to_array($subject->all()); then assert on $items for further checks","If the code under test can reasonably expose an array or Countable, change its return type so counting is safe"],"exampleFix":"// before\n$subjects = SubjectRepository::streamAll(); // Generator\n$this->assertCount(2, $subjects);\n// GeneratorNotSupportedException\n\n// after\n$subjects = iterator_to_array(SubjectRepository::streamAll());\n$this->assertCount(2, $subjects);","handlingStrategy":"type-guard","validationCode":"static function countableValue(mixed $value): array\n{\n    return $value instanceof \\Generator ? iterator_to_array($value) : $value;\n}","typeGuard":"static function isGenerator(mixed $value): bool\n{\n    return $value instanceof \\Generator;\n}","tryCatchPattern":"use PHPUnit\\Framework\\GeneratorNotSupportedException;\n\ntry {\n    $this->assertCount($n, $value);\n} catch (GeneratorNotSupportedException $e) {\n    // materialize once, then assert on the array\n    $this->assertCount($n, iterator_to_array($value));\n}","preventionTips":["Materialize generator results once into a variable right after the call, then assert on that variable","For size-only checks use iterator_count($gen) deliberately, knowing it consumes the generator","Type producers clearly (Generator vs array) so mismatches appear in static analysis"],"tags":["phpunit","assertion","generator","count"],"backgroundTag":"generator-not-countable","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}