{"id":"2d26e2820bdc76c9","repo":"junit-team/junit5","slug":"implement-generatedisplaynamefornestedclass-list-c","errorCode":null,"errorMessage":"Implement generateDisplayNameForNestedClass(List<Class<?>>, Class<?>) instead","messagePattern":"Implement generateDisplayNameForNestedClass\\(List<Class<\\?>>, Class<\\?>\\) instead","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGenerator.java","lineNumber":118,"sourceCode":"\t * @return the display name for the class; never blank\n\t */\n\tString generateDisplayNameForClass(Class<?> testClass);\n\n\t/**\n\t * Generate a display name for the given {@link Nested @Nested} inner test\n\t * class.\n\t *\n\t * <p>If this method returns {@code null}, the default display name\n\t * generator will be used instead.\n\t *\n\t * @param nestedClass the class to generate a name for; never {@code null}\n\t * @return the display name for the nested class; never blank\n\t * @deprecated in favor of {@link #generateDisplayNameForNestedClass(List, Class)}\n\t */\n\t@API(status = DEPRECATED, since = \"5.12\")\n\t@Deprecated(since = \"5.12\")\n\tdefault String generateDisplayNameForNestedClass(Class<?> nestedClass) {\n\t\tthrow new UnsupportedOperationException(\n\t\t\t\"Implement generateDisplayNameForNestedClass(List<Class<?>>, Class<?>) instead\");\n\t}\n\n\t/**\n\t * Generate a display name for the given {@link Nested @Nested} inner test\n\t * class.\n\t *\n\t * <p>If this method returns {@code null}, the default display name\n\t * generator will be used instead.\n\t *\n\t * @implNote The classes supplied as {@code enclosingInstanceTypes} may\n\t * differ from the classes returned from invocations of\n\t * {@link Class#getEnclosingClass()} &mdash; for example, when a nested test\n\t * class is inherited from a superclass.\n\t *\n\t * @param enclosingInstanceTypes the runtime types of the enclosing\n\t * instances for the test class, ordered from outermost to innermost,\n\t * excluding {@code nestedClass}; never {@code null}","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/junit-team/junit5/blob/956246301e03d757539f7b76dd5a91f298637563/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGenerator.java#L100-L136","documentation":"Thrown as UnsupportedOperationException by the deprecated default method generateDisplayNameForNestedClass(Class<?>) on the DisplayNameGenerator interface. Since 5.12 the new signature is generateDisplayNameForNestedClass(List<Class<?>>, Class<?>); the old method now throws by default to push implementors onto the new signature. The new default delegates to the old one, so a custom generator that overrides neither will hit this when a @Nested test is rendered.","triggerScenarios":"A custom DisplayNameGenerator implementation (registered globally via junit.jupiter.displayname.generator.default or locally via @DisplayNameGeneration) that does NOT override the new generateDisplayNameForNestedClass(List<Class<?>>, Class<?>) method, when JUnit renders a @Nested test class display name. The new default routes to the old default which throws.","commonSituations":"Custom DisplayNameGenerator written before 5.12 that overrode the single-arg method, then upgraded; the override no longer matches the new signature and silently falls through to the throwing default. Also a fresh generator where the author only implemented generateDisplayNameForClass and forgot nested classes.","solutions":["Override the new method in your custom generator: generateDisplayNameForNestedClass(List<Class<?>> enclosingInstanceTypes, Class<?> nestedClass).","If migrating, change the old override's signature to the new one (add the enclosingInstanceTypes parameter) and adapt the body.","Prefer extending a built-in base (DisplayNameGenerator.Standard / Simple / ReplaceUnderscores / IndicativeSentences) which already implement the new signature, instead of implementing the interface from scratch."],"exampleFix":"// before\npublic class MyGenerator implements DisplayNameGenerator {\n    public String generateDisplayNameForNestedClass(Class<?> nestedClass) { // deprecated, no longer called\n        return nestedClass.getSimpleName();\n    }\n}\n\n// after\n@Override\npublic String generateDisplayNameForNestedClass(List<Class<?>> enclosingInstanceTypes, Class<?> nestedClass) {\n    return nestedClass.getSimpleName();\n}","handlingStrategy":"type-guard","validationCode":"// At registration time, check that your generator implements the new nested-class method\nClass<? extends DisplayNameGenerator> g = MyGenerator.class;\nboolean hasNewNested = Arrays.stream(g.getMethods())\n    .anyMatch(m -> m.getName().equals(\"generateDisplayNameForNestedClass\")\n        && m.getParameterCount() == 2);\nif (!hasNewNested) throw new IllegalStateException(g + \" must implement generateDisplayNameForNestedClass(List, Class)\");","typeGuard":"static boolean implementsNewNestedSignature(Class<? extends DisplayNameGenerator> g) {\n    try {\n        return g.getMethod(\"generateDisplayNameForNestedClass\", java.util.List.class, Class.class)\n                .getDeclaringClass() == g;\n    } catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":null,"preventionTips":["When implementing DisplayNameGenerator, override the 5.12+ signatures that take List<Class<?>> enclosingInstanceTypes.","Prefer extending DisplayNameGenerator.Standard over implementing the interface directly.","After a JUnit upgrade, run a single @Nested test to confirm your generator does not throw UOE."],"tags":["display-name-generator","migration","nested-test","deprecation","junit-jupiter"],"analyzedSha":"956246301e03d757539f7b76dd5a91f298637563","analyzedAt":"2026-08-04T19:25:17.049Z","schemaVersion":2}