{"id":"689abae3f9fd80ff","repo":"junit-team/junit5","slug":"implement-generatedisplaynameformethod-list-class","errorCode":null,"errorMessage":"Implement generateDisplayNameForMethod(List<Class<?>>, Class<?>, Method) instead","messagePattern":"Implement generateDisplayNameForMethod\\(List<Class<\\?>>, Class<\\?>, Method\\) instead","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGenerator.java","lineNumber":164,"sourceCode":"\t/**\n\t * Generate a display name for the given method.\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 class instance supplied as {@code testClass} may differ from\n\t * the class returned by {@code testMethod.getDeclaringClass()} &mdash; for\n\t * example, when a test method is inherited from a superclass.\n\t *\n\t * @param testClass the class the test method is invoked on; never {@code null}\n\t * @param testMethod method to generate a display name for; never {@code null}\n\t * @return the display name for the test; never blank\n\t * @deprecated in favor of {@link #generateDisplayNameForMethod(List, Class, Method)}\n\t */\n\t@API(status = DEPRECATED, since = \"5.12\")\n\t@Deprecated(since = \"5.12\")\n\tdefault String generateDisplayNameForMethod(Class<?> testClass, Method testMethod) {\n\t\tthrow new UnsupportedOperationException(\n\t\t\t\"Implement generateDisplayNameForMethod(List<Class<?>>, Class<?>, Method) instead\");\n\t}\n\n\t/**\n\t * Generate a display name for the given method.\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. Similarly, the class instance\n\t * supplied as {@code testClass} may differ from the class returned by\n\t * {@code testMethod.getDeclaringClass()} &mdash; for example, when a test\n\t * method is inherited from a superclass.\n\t *\n\t * @param enclosingInstanceTypes the runtime types of the enclosing","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/junit-team/junit5/blob/956246301e03d757539f7b76dd5a91f298637563/junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGenerator.java#L146-L182","documentation":"Thrown as UnsupportedOperationException by the deprecated default method generateDisplayNameForMethod(Class<?>, Method) on the DisplayNameGenerator interface. Since 5.12 the new signature is generateDisplayNameForMethod(List<Class<?>>, Class<?>, Method); the old method throws by default. The new default delegates to the old one, so a custom generator overriding neither will hit this for every test method rendered.","triggerScenarios":"A custom DisplayNameGenerator (global or via @DisplayNameGeneration) that does NOT override generateDisplayNameForMethod(List<Class<?>>, Class<?>, Method), when JUnit renders any @Test/@RepeatedTest/@ParameterizedTest/@TestFactory method display name.","commonSituations":"Pre-5.12 custom generator that overrode the two-arg method, upgraded without updating the signature; or a new generator where only generateDisplayNameForClass was implemented. Symptom: every method in the test report aborts display-name generation with this UOE.","solutions":["Override the new method: generateDisplayNameForMethod(List<Class<?>> enclosingInstanceTypes, Class<?> testClass, Method testMethod).","If migrating, widen the old override to the new three-arg signature and reuse the body.","Extend DisplayNameGenerator.Standard / Simple / ReplaceUnderscores instead of implementing the interface directly."],"exampleFix":"// before\npublic String generateDisplayNameForMethod(Class<?> testClass, Method testMethod) { // deprecated\n    return testMethod.getName();\n}\n\n// after\n@Override\npublic String generateDisplayNameForMethod(List<Class<?>> enclosingInstanceTypes, Class<?> testClass, Method testMethod) {\n    return testMethod.getName();\n}","handlingStrategy":"type-guard","validationCode":"Class<? extends DisplayNameGenerator> g = MyGenerator.class;\nboolean hasNewMethod = Arrays.stream(g.getMethods())\n    .anyMatch(m -> m.getName().equals(\"generateDisplayNameForMethod\")\n        && m.getParameterCount() == 3);\nif (!hasNewMethod) throw new IllegalStateException(g + \" must implement generateDisplayNameForMethod(List, Class, Method)\");","typeGuard":"static boolean implementsNewMethodSignature(Class<? extends DisplayNameGenerator> g) {\n    try {\n        return g.getMethod(\"generateDisplayNameForMethod\", java.util.List.class, Class.class, java.lang.reflect.Method.class)\n                .getDeclaringClass() == g;\n    } catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":null,"preventionTips":["Always override generateDisplayNameForMethod(List<Class<?>>, Class<?>, Method) on custom generators.","Extend DisplayNameGenerator.Standard / Simple to inherit a correct implementation.","Add a smoke test that renders a @Test method display name through your generator."],"tags":["display-name-generator","migration","method-display-name","deprecation","junit-jupiter"],"analyzedSha":"956246301e03d757539f7b76dd5a91f298637563","analyzedAt":"2026-08-04T19:25:17.049Z","schemaVersion":2}