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

  1. Override generateDisplayNameForMethod(List<Class<?>> enclosingInstanceTypes, Class<?> testClass, Method testMethod) in your generator.
  2. Subclass Standard/Simple/IndicativeSentences and override only the new method to keep defaults intact.
  3. 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

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


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()} &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 f070c699a0)