java:S1144 false positive for fully-qualified @MethodSource reference in JUnit 5

Product: SonarQube Community 26.4.0.121862
sonar-java version: sonar-java 8.28.0.43176
sonar-java SE version: sonar-java-symbolic-execution 8.16.3.1589
Java source level: 21 (javac 21, source/target 17)

Rule

java:S1144 — Unused “private” methods should be removed

Description

JUnit 5’s @MethodSource annotation accepts either a simple method name (e.g. "trimAndUpperCaseArguments") or a fully-qualified reference of the form "<FQCN>#<methodName>" (e.g. "demo.after.StringUtilsTest#trimAndUpperCaseArguments"). Both forms reference the same private factory method at runtime.

SonarJava correctly recognizes the simple form as a usage of the private method, but fails to resolve the fully-qualified form and incorrectly reports the referenced private method as unused.

Reproducer


// BEFORE — simple name: no S1144 raised (correctly recognized as used)
@ParameterizedTest
@MethodSource("trimAndUpperCaseArguments")
void trimAndUpperCaseTest(final String expected, final String input) {
    assertEquals(expected, StringUtilsTest.trimAndUpperCase(input));
}

private static Stream<Arguments> trimAndUpperCaseArguments() {
    return Stream.of(
        Arguments.of("HELLO", "  hello  "),
        Arguments.of("WORLD", "world")
    );
}
// AFTER — fully-qualified reference: S1144 falsely raised
@ParameterizedTest
@MethodSource("demo.after.StringUtilsTest#trimAndUpperCaseArguments")
void trimAndUpperCaseTest(final String expected, final String input) {
    assertEquals(expected, StringUtilsTest.trimAndUpperCase(input));
}

private static Stream<Arguments> trimAndUpperCaseArguments() {
    return Stream.of(
        Arguments.of("HELLO", "  hello  "),
        Arguments.of("WORLD", "world")
    );
}

Hi @Emilyaxe,

Thank you for reporting this! The rule indeed fails to detect the method usage when the fully qualified name is provided. I have created a ticket to fix the false positive: SONARJAVA-6346

Best,
Noemie