{"record":{"id":"cd9c15a0d4cec9c3","repo":"mockito/mockito","slug":"it-is-not-possible-to-create-a-singleton-mock-of-c","errorCode":null,"errorMessage":"It is not possible to create a singleton mock of ConcurrentHashMap to avoid infinite loops within Mockito's implementation of mock handling","messagePattern":"It is not possible to create a singleton mock of ConcurrentHashMap to avoid infinite loops within Mockito's implementation of mock handling","errorType":"exception","errorClass":"MockitoException","httpStatus":null,"severity":"error","filePath":"mockito-core/src/main/java/org/mockito/internal/creation/bytebuddy/InlineDelegateByteBuddyMockMaker.java","lineNumber":691,"sourceCode":"\n        Map<Class<?>, BiConsumer<Object, MockedConstruction.Context>> interceptors =\n                mockedConstruction.get();\n        if (interceptors == null) {\n            interceptors = new WeakHashMap<>();\n            mockedConstruction.set(interceptors);\n        }\n        mockedConstruction.getBackingMap().expungeStaleEntries();\n\n        return new InlineConstructionMockControl<>(\n                type, settingsFactory, handlerFactory, mockInitializer, interceptors);\n    }\n\n    @Override\n    @SuppressWarnings(\"unchecked\")\n    public <T> SingletonMockControl<T> createSingletonMock(\n            T instance, MockCreationSettings<T> settings, MockHandler<T> handler) {\n        if (instance.getClass() == ConcurrentHashMap.class) {\n            throw new MockitoException(\n                    \"It is not possible to create a singleton mock of ConcurrentHashMap \"\n                            + \"to avoid infinite loops within Mockito's implementation of mock handling\");\n        }\n\n        // Instrument the class\n        createMockType(settings);\n\n        Map<Object, MockMethodInterceptor> singletons = mockedSingletons.get();\n        if (singletons == null) {\n            singletons = new WeakIdentityMap<>();\n            mockedSingletons.set(singletons);\n        }\n        mockedSingletons.getBackingMap().expungeStaleEntries();\n\n        return new InlineSingletonMockControl<>(instance, singletons, settings, handler);\n    }\n\n    @Override","sourceCodeStart":673,"sourceCodeEnd":709,"githubUrl":"https://github.com/mockito/mockito/blob/5a676bcd9ef9a10db46e1dc34e190eb46faa2687/mockito-core/src/main/java/org/mockito/internal/creation/bytebuddy/InlineDelegateByteBuddyMockMaker.java#L673-L709","documentation":"A singleton mock instruments the instance's class so all calls on that specific instance are intercepted. Because Mockito's own mock handling uses ConcurrentHashMap internally, making a ConcurrentHashMap instance a singleton mock would cause Mockito to intercept its own internal operations and loop infinitely. createSingletonMock rejects instances of ConcurrentHashMap with a MockitoException.","triggerScenarios":"Calling Mockito.mockSingleton(instance) (singleton-mock API) where the instance's runtime class is exactly ConcurrentHashMap, or passing such an instance through a generic helper.","commonSituations":"Test helpers that singleton-mock whatever instance a test provides; attempting to stub behavior of a shared concurrent map instance in legacy code.","solutions":["Wrap the ConcurrentHashMap behind your own interface/class and singleton-mock the wrapper","Pass a different, mockable instance; only ConcurrentHashMap itself is excluded","Refactor the code under test to accept an injectable Map abstraction","Use a real ConcurrentHashMap and adjust test expectations instead of instrumentation"],"exampleFix":"// before\nConcurrentHashMap<String,String> map = new ConcurrentHashMap<>();\nMockito.mockSingleton(map); // throws\n// after\ninterface SharedMap { String get(String k); }\nclass ConcurrentSharedMap implements SharedMap { ... }\nSharedMap m = Mockito.mockSingleton(new ConcurrentSharedMap()); // mock the wrapper type","handlingStrategy":"validation","validationCode":"static void assertSingletonMockable(Object instance) {\n    if (instance.getClass() == java.util.concurrent.ConcurrentHashMap.class) {\n        throw new IllegalArgumentException(\"Cannot singleton-mock ConcurrentHashMap instances\");\n    }\n}\n// before mockSingleton: assertSingletonMockable(instance);","typeGuard":"static boolean canSingletonMock(Object instance) {\n    return instance != null && instance.getClass() != java.util.concurrent.ConcurrentHashMap.class;\n}","tryCatchPattern":"try {\n    control = Mockito.mockSingleton(chmInstance);\n} catch (org.mockito.exceptions.base.MockitoException e) {\n    if (e.getMessage().contains(\"ConcurrentHashMap\")) {\n        // wrap the map behind an interface and mock the wrapper\n    } else {\n        throw e;\n    }\n}","preventionTips":["Never singleton-mock ConcurrentHashMap instances","Abstract concurrent-map access behind your own interface","In generic mockSingleton helpers, check instance.getClass() against the blacklist","Use real map instances with adjusted expectations where possible"],"tags":["mockito","singleton-mock","concurrenthashmap","unsupported-mock"],"backgroundTag":"mockito-unsupported-mock-target","analyzedSha":"5a676bcd9ef9a10db46e1dc34e190eb46faa2687","analyzedAt":"2026-09-05T19:32:58.607Z","contentChangedAt":"2026-09-05T19:32:58.607Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}