junit-team/junit5 · error · UnsupportedOperationException
Implement generateDisplayNameForNestedClass(List<Class<?>>,
Error message
Implement generateDisplayNameForNestedClass(List<Class<?>>, Class<?>) instead
What it means
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.
Source
Thrown at junit-jupiter-api/src/main/java/org/junit/jupiter/api/DisplayNameGenerator.java:118
* @return the display name for the class; never blank
*/
String generateDisplayNameForClass(Class<?> testClass);
/**
* Generate a display name for the given {@link Nested @Nested} inner test
* class.
*
* <p>If this method returns {@code null}, the default display name
* generator will be used instead.
*
* @param nestedClass the class to generate a name for; never {@code null}
* @return the display name for the nested class; never blank
* @deprecated in favor of {@link #generateDisplayNameForNestedClass(List, Class)}
*/
@API(status = DEPRECATED, since = "5.12")
@Deprecated(since = "5.12")
default String generateDisplayNameForNestedClass(Class<?> nestedClass) {
throw new UnsupportedOperationException(
"Implement generateDisplayNameForNestedClass(List<Class<?>>, Class<?>) instead");
}
/**
* Generate a display name for the given {@link Nested @Nested} inner test
* class.
*
* <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.
*
* @param enclosingInstanceTypes the runtime types of the enclosing
* instances for the test class, ordered from outermost to innermost,
* excluding {@code nestedClass}; never {@code null}View on GitHub (pinned to 956246301e)
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.
Example fix
// before
public class MyGenerator implements DisplayNameGenerator {
public String generateDisplayNameForNestedClass(Class<?> nestedClass) { // deprecated, no longer called
return nestedClass.getSimpleName();
}
}
// after
@Override
public String generateDisplayNameForNestedClass(List<Class<?>> enclosingInstanceTypes, Class<?> nestedClass) {
return nestedClass.getSimpleName();
} Defensive patterns
Strategy: type-guard
Validate before calling
// At registration time, check that your generator implements the new nested-class method
Class<? extends DisplayNameGenerator> g = MyGenerator.class;
boolean hasNewNested = Arrays.stream(g.getMethods())
.anyMatch(m -> m.getName().equals("generateDisplayNameForNestedClass")
&& m.getParameterCount() == 2);
if (!hasNewNested) throw new IllegalStateException(g + " must implement generateDisplayNameForNestedClass(List, Class)"); Type guard
static boolean implementsNewNestedSignature(Class<? extends DisplayNameGenerator> g) {
try {
return g.getMethod("generateDisplayNameForNestedClass", java.util.List.class, Class.class)
.getDeclaringClass() == g;
} catch (NoSuchMethodException e) { return false; }
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Implement generateDisplayNameForMethod(List<Class<?>>, Class
- Assumption failed:
- Assumption failed
- This class must not be instantiated
- This class must not be instantiated
AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04).
Data as JSON: /data/errors/2d26e2820bdc76c9.json.
Report an issue: GitHub.