{"record":{"id":"d94fded42ed03ef0","repo":"sebastianbergmann/phpunit","slug":"class-s-is-an-anonymous-class-and-cannot-be-dou","errorCode":null,"errorMessage":"Class \"%s\" is an anonymous class and cannot be doubled","messagePattern":"Class \"(.+?)\" is an anonymous class and cannot be doubled","errorType":"exception","errorClass":"ClassIsAnonymousException","httpStatus":null,"severity":"error","filePath":"src/Framework/MockObject/Generator/Generator.php","lineNumber":386,"sourceCode":"        $mockMethods           = new DoubledMethodSet;\n        $testDoubleClassPrefix = $mockObject ? 'MockObject_' : 'TestStub_';\n\n        $_mockClassName = $this->generateClassName(\n            $type,\n            $mockClassName,\n            $testDoubleClassPrefix,\n        );\n\n        if (class_exists($_mockClassName['fullClassName'])) {\n            $isClass = true;\n        } elseif (interface_exists($_mockClassName['fullClassName'])) {\n            $isInterface = true;\n        }\n\n        $class = $this->reflectClass($_mockClassName['fullClassName']);\n\n        if ($class->isAnonymous()) {\n            throw new ClassIsAnonymousException($_mockClassName['fullClassName']);\n        }\n\n        if ($class->isEnum()) {\n            throw new ClassIsEnumerationException($_mockClassName['fullClassName']);\n        }\n\n        if ($class->isFinal()) {\n            throw new ClassIsFinalException($_mockClassName['fullClassName']);\n        }\n\n        if ($class->isReadOnly()) {\n            $isReadonly = true;\n        }\n\n        // @see https://github.com/sebastianbergmann/phpunit/issues/2995\n        if ($isInterface && $class->implementsInterface(Throwable::class)) {\n            $actualClassName        = Exception::class;\n            $additionalInterfaces[] = $class->getName();","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Framework/MockObject/Generator/Generator.php#L368-L404","documentation":"Before generating a test double, PHPUnit reflects the target class and rejects anonymous classes (ReflectionClass::isAnonymous()). Mocks are built by generating a subclass named after the original; an anonymous class has no stable name that can serve as a parent, so it cannot be doubled.","triggerScenarios":"createMock() (or createStub, or MockBuilder) given an anonymous class: e.g. $anon = new class {}; createMock(get_class($anon)) — get_class() returns something like 'app\\...\\class@anonymous...' which reflects as anonymous and triggers the exception.","commonSituations":"Tests for factories that return throwaway anonymous implementations; capturing an object from SUT and trying to mock its dynamic type; using new class extends SomeBase inline in fixtures then attempting to double it.","solutions":["Extract the anonymous class into a named (possibly internal/test-only) class and mock that name","Mock the interface/base class the anonymous class implements instead of the anonymous type itself","For simple stand-ins, build the anonymous object by hand with the behavior you need instead of mocking it"],"exampleFix":"// before\n$handler = new class implements HandlerInterface { ... };\n$mock = $this->createMock(get_class($handler)); // anonymous -> exception\n\n// after\n$mock = $this->createMock(HandlerInterface::class);","handlingStrategy":"validation","validationCode":"$type = $object::class;\nif ((new ReflectionClass($type))->isAnonymous()) {\n    $type = class_implements($object)[0] ?? get_parent_class($object);\n}\n$mock = $this->createMock($type);","typeGuard":"function isMockableType(string $type): bool\n{\n    if (!class_exists($type) && !interface_exists($type)) {\n        return false;\n    }\n    $r = new ReflectionClass($type);\n    return !$r->isAnonymous() && !$r->isEnum() && !$r->isFinal();\n}","tryCatchPattern":null,"preventionTips":["Never derive a mock target from get_class() of an object that might be anonymous — type against interfaces","Give fixtures named test-double classes instead of inline `new class`"],"tags":["php","phpunit","mockbuilder","anonymous-class","createmock"],"backgroundTag":"unmockable-type","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}