junit-team/junit5 · error · UnsupportedOperationException

Implement generateDisplayNameForNestedClass(List<Class<?>>…

Error message

Implement generateDisplayNameForNestedClass(List<Class<?>>, Class<?>) instead

What it means

Default method of the deprecated single-arg generateDisplayNameForNestedClass(Class<?>) on DisplayNameGenerator, deprecated since 5.12 in favor of generateDisplayNameForNestedClass(List<Class<?>>, Class<?>). The default body throws UnsupportedOperationException to force subclasses to implement the new overloaded form rather than relying on the old one. A generator that does not override the new method will abort display-name generation for @Nested classes.

Solutions

  1. Implement the new signature generateDisplayNameForNestedClass(List<Class<?>> enclosingInstanceTypes, Class<?> nestedClass) in your custom DisplayNameGenerator.
  2. Subclass an existing generator (Standard, Simple, IndicativeSentences) and override only what you need, so defaults are inherited correctly.
  3. If you must support the old signature transiently, override both methods and delegate, but plan to remove the old override when you drop pre-5.12 support.

Example fix

// before
@Override
public String generateDisplayNameForNestedClass(Class<?> nestedClass) {
    return nestedClass.getSimpleName();
}
// after
@Override
public String generateDisplayNameForNestedClass(List<Class<?>> enclosingInstanceTypes,
        Class<?> nestedClass) {
    return nestedClass.getSimpleName();
}
Defensive patterns

Strategy: type-guard

Validate before calling

assert !overridesOnlyOldNested(generator.getClass()) : "implement new List/Class overload";

Type guard

static boolean implementsNewNested(DisplayNameGenerator g) {
    try {
        return g.getClass().getMethod("generateDisplayNameForNestedClass", List.class, Class.class)
                 .getDeclaringClass() == g.getClass();
    } catch (NoSuchMethodException e) { return false; }
}

Prevention

When it happens

Trigger: A custom DisplayNameGenerator implementation that overrides neither the old nor the new generateDisplayNameForNestedClass, yet is selected (via @DisplayNameGeneration) for a test class containing @Nested classes — the inherited default method runs and throws.

Common situations: Upgrading to JUnit 5.12+ with a pre-existing custom DisplayNameGenerator that only overrode some methods; relying on interface defaults that no longer exist; a generator written for an older API surface.

Related errors


AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11). Data as JSON: /api/errors/2d26e2820bdc76c9. Report an issue: GitHub.

Appendix: 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()} &mdash; 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 f070c699a0)