junit-team/junit5 · error · UnsupportedOperationException

Implement generateDisplayNameForMethod(List<Class<?>>, Class

Error message

Implement generateDisplayNameForMethod(List<Class<?>>, Class<?>, Method) instead

What it means

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.

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()} &mdash; 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()} &mdash; 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()} &mdash; for example, when a test
	 * method is inherited from a superclass.
	 *
	 * @param enclosingInstanceTypes the runtime types of the enclosing

View on GitHub (pinned to 956246301e)

Solutions

  1. Override the new method: generateDisplayNameForMethod(List<Class<?>> enclosingInstanceTypes, Class<?> testClass, Method testMethod).
  2. If migrating, widen the old override to the new three-arg signature and reuse the body.
  3. Extend DisplayNameGenerator.Standard / Simple / ReplaceUnderscores instead of implementing the interface directly.

Example fix

// before
public String generateDisplayNameForMethod(Class<?> testClass, Method testMethod) { // deprecated
    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

Class<? extends DisplayNameGenerator> g = MyGenerator.class;
boolean hasNewMethod = Arrays.stream(g.getMethods())
    .anyMatch(m -> m.getName().equals("generateDisplayNameForMethod")
        && m.getParameterCount() == 3);
if (!hasNewMethod) throw new IllegalStateException(g + " must implement generateDisplayNameForMethod(List, Class, Method)");

Type guard

static boolean implementsNewMethodSignature(Class<? extends DisplayNameGenerator> g) {
    try {
        return g.getMethod("generateDisplayNameForMethod", java.util.List.class, Class.class, java.lang.reflect.Method.class)
                .getDeclaringClass() == g;
    } catch (NoSuchMethodException e) { return false; }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of junit-team/junit5@956246301e (2026-08-04). Data as JSON: /data/errors/689abae3f9fd80ff.json. Report an issue: GitHub.