28
28
import org .junit .jupiter .api .extension .ExtensionContext ;
29
29
import org .junit .jupiter .params .support .AnnotationConsumer ;
30
30
import org .junit .platform .commons .JUnitException ;
31
+ import org .junit .platform .commons .util .ClassUtils ;
31
32
import org .junit .platform .commons .util .CollectionUtils ;
32
33
import org .junit .platform .commons .util .Preconditions ;
33
34
import org .junit .platform .commons .util .ReflectionUtils ;
@@ -62,10 +63,21 @@ private Method getFactoryMethod(ExtensionContext context, String factoryMethodNa
62
63
if (StringUtils .isBlank (factoryMethodName )) {
63
64
factoryMethodName = testMethod .getName ();
64
65
}
65
- if (factoryMethodName . contains ( "." ) || factoryMethodName . contains ( "#" )) {
66
+ if (looksLikeAFullyQualifiedMethodName ( factoryMethodName )) {
66
67
return getFactoryMethodByFullyQualifiedName (factoryMethodName );
67
68
}
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 ("." );
69
81
}
70
82
71
83
private Method getFactoryMethodByFullyQualifiedName (String fullyQualifiedMethodName ) {
@@ -79,19 +91,41 @@ private Method getFactoryMethodByFullyQualifiedName(String fullyQualifiedMethodN
79
91
methodParameters , className )));
80
92
}
81
93
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
+
82
113
/**
83
114
* Find all methods in the given {@code testClass} with the desired {@code factoryMethodName}
84
115
* which have return types that can be converted to a {@link Stream}, ignoring the
85
116
* {@code testMethod} itself as well as any {@code @Test}, {@code @TestTemplate},
86
117
* or {@code @TestFactory} methods with the same name.
87
118
*/
88
- private Method getFactoryMethodBySimpleName (Class <?> testClass , Method testMethod , String factoryMethodName ) {
119
+ private List <Method > findFactoryMethodsBySimpleName (Class <?> testClass , Method testMethod ,
120
+ String factoryMethodName ) {
89
121
Predicate <Method > isCandidate = candidate -> factoryMethodName .equals (candidate .getName ())
90
122
&& !testMethod .equals (candidate );
91
123
List <Method > candidates = ReflectionUtils .findMethods (testClass , isCandidate );
124
+
92
125
Predicate <Method > isFactoryMethod = method -> isConvertibleToStream (method .getReturnType ())
93
126
&& !isTestMethod (method );
94
127
List <Method > factoryMethods = candidates .stream ().filter (isFactoryMethod ).collect (toList ());
128
+
95
129
Preconditions .condition (factoryMethods .size () > 0 , () -> {
96
130
// If we didn't find the factory method using the isFactoryMethod Predicate, perhaps
97
131
// 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
104
138
// Otherwise, report that we didn't find anything.
105
139
return format ("Could not find factory method [%s] in class [%s]" , factoryMethodName , testClass .getName ());
106
140
});
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 ());
111
153
}
112
154
113
155
private boolean isTestMethod (Method candidate ) {
0 commit comments