junit-team/junit5 · error · UnsupportedOperationException
Implement generateDisplayNameForMethod(List<Class<?>>…
Error message
Implement generateDisplayNameForMethod(List<Class<?>>, Class<?>, Method) instead
What it means
Default method of the deprecated two-arg generateDisplayNameForMethod(Class<?>, Method) on DisplayNameGenerator, deprecated since 5.12 in favor of generateDisplayNameForMethod(List<Class<?>>, Class<?>, Method). The default implementation throws UnsupportedOperationException so custom generators must implement the new arity. Hitting it means display-name generation for a method was dispatched to the un-overridden old method.
Solutions
- Override generateDisplayNameForMethod(List<Class<?>> enclosingInstanceTypes, Class<?> testClass, Method testMethod) in your generator.
- Subclass Standard/Simple/IndicativeSentences and override only the new method to keep defaults intact.
- Remove any override of the deprecated two-arg method to avoid dispatching to it accidentally.
Example fix
// before
@Override
public String generateDisplayNameForMethod(Class<?> testClass, Method testMethod) {
return testMethod.getName();
}
// after
@Override
public String generateDisplayNameForMethod(List<Class<?>> enclosingInstanceTypes,
Class<?> testClass, Method testMethod) {
return testMethod.getName();
} Defensive patterns
Strategy: type-guard
Validate before calling
assert implementsNewMethod(generator.getClass()) : "implement new List/Class/Method overload";
Type guard
static boolean implementsNewMethod(Class<? extends DisplayNameGenerator> c) {
try {
return c.getMethod("generateDisplayNameForMethod", List.class, Class.class, Method.class)
.getDeclaringClass() == c;
} catch (NoSuchMethodException e) { return false; }
} Prevention
- Target the three-arg method overload on upgrade.
- Subclass an existing generator to keep defaults intact.
- Remove deprecated two-arg overrides to prevent accidental dispatch.
When it happens
Trigger: A custom DisplayNameGenerator selected via @DisplayNameGeneration that does not override the new three-arg method, when JUnit requests a method display name — the inherited default throws.
Common situations: Pre-5.12 custom DisplayNameGenerator carried forward after upgrade; generators built by copying an old example that only overrode the two-arg method; parameterized-test display customization that targeted the wrong overload.
Related errors
- Implement generateDisplayNameForNestedClass(List<Class<?>>…
- AnnotationBasedArgumentsProvider does not override the…
- ArgumentsProvider does not override the…
- Please implement provideArguments(ParameterDeclarations…
- Failed to format display name for parameterized test. See…
AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11).
Data as JSON: /api/errors/689abae3f9fd80ff.
Report an issue: GitHub.
Appendix: source
Thrown at junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGenerator.java:164
/**
* Generate a display name for the given method.
*
* <p>If this method returns {@code null}, the default display name
* generator will be used instead.
*
* @implNote The class instance supplied as {@code testClass} may differ from
* the class returned by {@code testMethod.getDeclaringClass()} — for
* example, when a test method is inherited from a superclass.
*
* @param testClass the class the test method is invoked on; never {@code null}
* @param testMethod method to generate a display name for; never {@code null}
* @return the display name for the test; never blank
* @deprecated in favor of {@link #generateDisplayNameForMethod(List, Class, Method)}
*/
@API(status = DEPRECATED, since = "5.12")
@Deprecated(since = "5.12")
default String generateDisplayNameForMethod(Class<?> testClass, Method testMethod) {
throw new UnsupportedOperationException(
"Implement generateDisplayNameForMethod(List<Class<?>>, Class<?>, Method) instead");
}
/**
* Generate a display name for the given method.
*
* <p>If this method returns {@code null}, the default display name
* generator will be used instead.
*
* @implNote The classes supplied as {@code enclosingInstanceTypes} may
* differ from the classes returned from invocations of
* {@link Class#getEnclosingClass()} — for example, when a nested test
* class is inherited from a superclass. Similarly, the class instance
* supplied as {@code testClass} may differ from the class returned by
* {@code testMethod.getDeclaringClass()} — for example, when a test
* method is inherited from a superclass.
*
* @param enclosingInstanceTypes the runtime types of the enclosingView on GitHub (pinned to f070c699a0)