2828import org .junit .jupiter .api .extension .ExtensionContext ;
2929import org .junit .jupiter .params .support .AnnotationConsumer ;
3030import org .junit .platform .commons .JUnitException ;
31+ import org .junit .platform .commons .util .ClassUtils ;
3132import org .junit .platform .commons .util .CollectionUtils ;
3233import org .junit .platform .commons .util .Preconditions ;
3334import org .junit .platform .commons .util .ReflectionUtils ;
@@ -62,10 +63,21 @@ private Method getFactoryMethod(ExtensionContext context, String factoryMethodNa
6263 if (StringUtils .isBlank (factoryMethodName )) {
6364 factoryMethodName = testMethod .getName ();
6465 }
65- if (factoryMethodName . contains ( "." ) || factoryMethodName . contains ( "#" )) {
66+ if (looksLikeAFullyQualifiedMethodName ( factoryMethodName )) {
6667 return getFactoryMethodByFullyQualifiedName (factoryMethodName );
6768 }
68- return getFactoryMethodBySimpleName (context .getRequiredTestClass (), testMethod , factoryMethodName );
69+ return getFactoryMethodBySimpleOrQualifiedName (context .getRequiredTestClass (), testMethod , factoryMethodName );
70+ }
71+
72+ private static boolean looksLikeAFullyQualifiedMethodName (String factoryMethodName ) {
73+ if (factoryMethodName .contains ("#" )) {
74+ return true ;
75+ }
76+ if (factoryMethodName .contains ("." ) && factoryMethodName .contains ("(" )) {
77+ // Excluding cases of simple method names with parameters
78+ return factoryMethodName .indexOf ("." ) < factoryMethodName .indexOf ("(" );
79+ }
80+ return factoryMethodName .contains ("." );
6981 }
7082
7183 private Method getFactoryMethodByFullyQualifiedName (String fullyQualifiedMethodName ) {
@@ -79,19 +91,41 @@ private Method getFactoryMethodByFullyQualifiedName(String fullyQualifiedMethodN
7991 methodParameters , className )));
8092 }
8193
94+ private Method getFactoryMethodBySimpleOrQualifiedName (Class <?> testClass , Method testMethod ,
95+ String simpleOrQualifiedMethodName ) {
96+ String [] methodParts = ReflectionUtils .parseQualifiedMethodName (simpleOrQualifiedMethodName );
97+ String methodSimpleName = methodParts [0 ];
98+ String methodParameters = methodParts [1 ];
99+
100+ List <Method > factoryMethods = findFactoryMethodsBySimpleName (testClass , testMethod , methodSimpleName );
101+ if (factoryMethods .size () == 1 ) {
102+ return factoryMethods .get (0 );
103+ }
104+
105+ List <Method > exactMatches = filterFactoryMethodsWithMatchingParameters (factoryMethods ,
106+ simpleOrQualifiedMethodName , methodParameters );
107+ Preconditions .condition (exactMatches .size () == 1 ,
108+ () -> format ("%d factory methods named [%s] were found in class [%s]: %s" , factoryMethods .size (),
109+ simpleOrQualifiedMethodName , testClass .getName (), factoryMethods ));
110+ return exactMatches .get (0 );
111+ }
112+
82113 /**
83114 * Find all methods in the given {@code testClass} with the desired {@code factoryMethodName}
84115 * which have return types that can be converted to a {@link Stream}, ignoring the
85116 * {@code testMethod} itself as well as any {@code @Test}, {@code @TestTemplate},
86117 * or {@code @TestFactory} methods with the same name.
87118 */
88- private Method getFactoryMethodBySimpleName (Class <?> testClass , Method testMethod , String factoryMethodName ) {
119+ private List <Method > findFactoryMethodsBySimpleName (Class <?> testClass , Method testMethod ,
120+ String factoryMethodName ) {
89121 Predicate <Method > isCandidate = candidate -> factoryMethodName .equals (candidate .getName ())
90122 && !testMethod .equals (candidate );
91123 List <Method > candidates = ReflectionUtils .findMethods (testClass , isCandidate );
124+
92125 Predicate <Method > isFactoryMethod = method -> isConvertibleToStream (method .getReturnType ())
93126 && !isTestMethod (method );
94127 List <Method > factoryMethods = candidates .stream ().filter (isFactoryMethod ).collect (toList ());
128+
95129 Preconditions .condition (factoryMethods .size () > 0 , () -> {
96130 // If we didn't find the factory method using the isFactoryMethod Predicate, perhaps
97131 // the specified factory method has an invalid return type or is a test method.
@@ -104,10 +138,18 @@ private Method getFactoryMethodBySimpleName(Class<?> testClass, Method testMetho
104138 // Otherwise, report that we didn't find anything.
105139 return format ("Could not find factory method [%s] in class [%s]" , factoryMethodName , testClass .getName ());
106140 });
107- Preconditions .condition (factoryMethods .size () == 1 ,
108- () -> format ("%d factory methods named [%s] were found in class [%s]: %s" , factoryMethods .size (),
109- factoryMethodName , testClass .getName (), factoryMethods ));
110- return factoryMethods .get (0 );
141+ return factoryMethods ;
142+ }
143+
144+ private static List <Method > filterFactoryMethodsWithMatchingParameters (List <Method > factoryMethods ,
145+ String factoryMethodName , String factoryMethodParameters ) {
146+ if (!factoryMethodName .endsWith (")" )) {
147+ // If parameters are not specified, no choice is made
148+ return factoryMethods ;
149+ }
150+ Predicate <Method > hasRequiredParameters = method -> factoryMethodParameters .equals (
151+ ClassUtils .nullSafeToString (method .getParameterTypes ()));
152+ return factoryMethods .stream ().filter (hasRequiredParameters ).collect (toList ());
111153 }
112154
113155 private boolean isTestMethod (Method candidate ) {
0 commit comments