2525import static org .junit .jupiter .engine .discovery .JupiterUniqueIdBuilder .uniqueIdForTestTemplateMethod ;
2626import static org .junit .jupiter .engine .discovery .JupiterUniqueIdBuilder .uniqueIdForTopLevelClass ;
2727import static org .junit .platform .commons .util .CollectionUtils .getOnlyElement ;
28+ import static org .junit .platform .engine .SelectorResolutionResult .Status .FAILED ;
29+ import static org .junit .platform .engine .SelectorResolutionResult .Status .RESOLVED ;
30+ import static org .junit .platform .engine .SelectorResolutionResult .Status .UNRESOLVED ;
2831import static org .junit .platform .engine .discovery .ClassNameFilter .includeClassNamePatterns ;
2932import static org .junit .platform .engine .discovery .DiscoverySelectors .selectClass ;
3033import static org .junit .platform .engine .discovery .DiscoverySelectors .selectClasspathRoots ;
3336import static org .junit .platform .engine .discovery .DiscoverySelectors .selectUniqueId ;
3437import static org .junit .platform .engine .discovery .PackageNameFilter .excludePackageNames ;
3538import static org .junit .platform .engine .discovery .PackageNameFilter .includePackageNames ;
36- import static org .junit .platform .launcher .core .LauncherDiscoveryRequestBuilder .request ;
39+ import static org .junit .platform .launcher .core .LauncherDiscoveryRequestBuilder .DEFAULT_DISCOVERY_LISTENER_CONFIGURATION_PROPERTY_NAME ;
40+ import static org .mockito .ArgumentMatchers .any ;
41+ import static org .mockito .ArgumentMatchers .eq ;
3742import static org .mockito .Mockito .mock ;
43+ import static org .mockito .Mockito .verify ;
3844import static org .mockito .Mockito .when ;
3945
4046import java .lang .reflect .Method ;
4450import java .nio .file .Paths ;
4551import java .util .ArrayList ;
4652import java .util .List ;
47- import java .util .logging .Level ;
48- import java .util .logging .LogRecord ;
53+ import java .util .function .Predicate ;
4954import java .util .stream .Stream ;
5055
5156import org .junit .jupiter .api .BeforeEach ;
5560import org .junit .jupiter .api .Test ;
5661import org .junit .jupiter .api .TestFactory ;
5762import org .junit .jupiter .api .TestTemplate ;
58- import org .junit .jupiter .api .fixtures .TrackLogRecords ;
5963import org .junit .jupiter .api .parallel .ExecutionMode ;
6064import org .junit .jupiter .engine .config .JupiterConfiguration ;
6165import org .junit .jupiter .engine .descriptor .DynamicDescendantFilter ;
6872import org .junit .jupiter .engine .descriptor .subpackage .ClassWithStaticInnerTestCases ;
6973import org .junit .platform .commons .JUnitException ;
7074import org .junit .platform .commons .PreconditionViolationException ;
71- import org .junit .platform .commons .logging .LogRecordListener ;
7275import org .junit .platform .commons .util .ReflectionUtils ;
76+ import org .junit .platform .engine .DiscoverySelector ;
77+ import org .junit .platform .engine .SelectorResolutionResult ;
7378import org .junit .platform .engine .TestDescriptor ;
7479import org .junit .platform .engine .UniqueId ;
7580import org .junit .platform .engine .discovery .ClassSelector ;
7681import org .junit .platform .engine .discovery .ClasspathRootSelector ;
7782import org .junit .platform .engine .discovery .MethodSelector ;
7883import org .junit .platform .engine .discovery .PackageSelector ;
7984import org .junit .platform .engine .discovery .UniqueIdSelector ;
80- import org .junit .platform .engine . support . discovery . EngineDiscoveryRequestResolver ;
85+ import org .junit .platform .launcher . LauncherDiscoveryListener ;
8186import org .junit .platform .launcher .core .LauncherDiscoveryRequestBuilder ;
87+ import org .mockito .ArgumentCaptor ;
8288
8389/**
8490 * @since 5.0
8591 */
8692class DiscoverySelectorResolverTests {
8793
8894 private final JupiterConfiguration configuration = mock (JupiterConfiguration .class );
95+ private final LauncherDiscoveryListener discoveryListener = mock (LauncherDiscoveryListener .class );
8996 private final JupiterEngineDescriptor engineDescriptor = new JupiterEngineDescriptor (engineId (), configuration );
9097
9198 @ BeforeEach
@@ -102,14 +109,11 @@ void nonTestClassResolution() {
102109 }
103110
104111 @ Test
105- @ TrackLogRecords
106- void abstractClassResolution (LogRecordListener listener ) {
112+ void abstractClassResolution () {
107113 resolve (request ().selectors (selectClass (AbstractTestClass .class )));
108114
109115 assertTrue (engineDescriptor .getDescendants ().isEmpty ());
110- assertThat (firstDebugLogRecord (listener ).getMessage ())//
111- .isEqualTo (
112- "ClassSelector [className = '" + AbstractTestClass .class .getName () + "'] could not be resolved." );
116+ assertUnresolved (selectClass (AbstractTestClass .class ));
113117 }
114118
115119 @ Test
@@ -123,15 +127,15 @@ void singleClassResolution() {
123127 }
124128
125129 @ Test
126- @ TrackLogRecords
127- void classResolutionForNonexistentClass (LogRecordListener listener ) {
130+ void classResolutionForNonexistentClass () {
128131 ClassSelector selector = selectClass ("org.example.DoesNotExist" );
129132
130133 resolve (request ().selectors (selector ));
131134
132135 assertTrue (engineDescriptor .getDescendants ().isEmpty ());
133- assertThat (firstDebugLogRecord (listener ).getMessage ())//
134- .isEqualTo ("ClassSelector [className = 'org.example.DoesNotExist'] could not be resolved." );
136+ var result = verifySelectorProcessed (selector );
137+ assertThat (result .getStatus ()).isEqualTo (FAILED );
138+ assertThat (result .getThrowable ().get ()).hasMessageContaining ("Could not load class with name" );
135139 }
136140
137141 @ Test
@@ -216,35 +220,31 @@ void resolvingSelectorOfNonTestMethodResolvesNothing() throws NoSuchMethodExcept
216220 }
217221
218222 @ Test
219- @ TrackLogRecords
220- void methodResolutionForNonexistentClass (LogRecordListener listener ) {
223+ void methodResolutionForNonexistentClass () {
221224 String className = "org.example.DoesNotExist" ;
222225 String methodName = "bogus" ;
223226 MethodSelector selector = selectMethod (className , methodName , "" );
224227
225228 resolve (request ().selectors (selector ));
226229
227230 assertTrue (engineDescriptor .getDescendants ().isEmpty ());
228- LogRecord logRecord = firstDebugLogRecord (listener );
229- assertThat (logRecord .getMessage ())//
230- .startsWith ("MethodSelector" ).endsWith ("could not be resolved." )//
231- .contains (className , methodName );
232- assertThat (logRecord .getThrown ())//
231+ var result = verifySelectorProcessed (selector );
232+ assertThat (result .getStatus ()).isEqualTo (FAILED );
233+ assertThat (result .getThrowable ().get ())//
233234 .isInstanceOf (PreconditionViolationException .class )//
234235 .hasMessageStartingWith ("Could not load class with name: " + className );
235236 }
236237
237238 @ Test
238- @ TrackLogRecords
239- void methodResolutionForNonexistentMethod (LogRecordListener listener ) {
239+ void methodResolutionForNonexistentMethod () {
240240 MethodSelector selector = selectMethod (MyTestClass .class , "bogus" , "" );
241241
242242 resolve (request ().selectors (selector ));
243243
244244 assertTrue (engineDescriptor .getDescendants ().isEmpty ());
245- assertThat ( firstDebugLogRecord ( listener ). getMessage ()) //
246- . startsWith ( "MethodSelector" ). endsWith ( "could not be resolved." ) //
247- . contains ( MyTestClass . class . getName (), "bogus " );
245+ var result = verifySelectorProcessed ( selector );
246+ assertThat ( result . getStatus ()). isEqualTo ( FAILED );
247+ assertThat ( result . getThrowable (). get ()). hasMessageContaining ( "Could not find method " );
248248 }
249249
250250 @ Test
@@ -285,16 +285,14 @@ void methodOfInnerClassByUniqueId() {
285285 }
286286
287287 @ Test
288- @ TrackLogRecords
289- void resolvingUniqueIdWithUnknownSegmentTypeResolvesNothing (LogRecordListener listener ) {
288+ void resolvingUniqueIdWithUnknownSegmentTypeResolvesNothing () {
290289 UniqueId uniqueId = engineId ().append ("bogus" , "enigma" );
291290 UniqueIdSelector selector = selectUniqueId (uniqueId );
292291
293292 resolve (request ().selectors (selector ));
294293
295294 assertTrue (engineDescriptor .getDescendants ().isEmpty ());
296- assertThat (firstWarningLogRecord (listener ).getMessage ()) //
297- .isEqualTo ("UniqueIdSelector [uniqueId = " + uniqueId + "] could not be resolved." );
295+ assertUnresolved (selector );
298296 }
299297
300298 @ Test
@@ -304,52 +302,47 @@ void resolvingUniqueIdOfNonTestMethodResolvesNothing() {
304302 resolve (request ().selectors (selector ));
305303
306304 assertThat (engineDescriptor .getDescendants ()).isEmpty ();
305+ assertUnresolved (selector );
307306 }
308307
309308 @ Test
310- @ TrackLogRecords
311- void methodResolutionByUniqueIdWithMissingMethodName (LogRecordListener listener ) {
309+ void methodResolutionByUniqueIdWithMissingMethodName () {
312310 UniqueId uniqueId = uniqueIdForMethod (getClass (), "()" );
313311
314312 resolve (request ().selectors (selectUniqueId (uniqueId )));
315313
316314 assertTrue (engineDescriptor .getDescendants ().isEmpty ());
317- LogRecord logRecord = firstWarningLogRecord (listener );
318- assertThat (logRecord .getMessage ()).isEqualTo (
319- "UniqueIdSelector [uniqueId = " + uniqueId + "] could not be resolved." );
320- assertThat (logRecord .getThrown ())//
315+ var result = verifySelectorProcessed (selectUniqueId (uniqueId ));
316+ assertThat (result .getStatus ()).isEqualTo (FAILED );
317+ assertThat (result .getThrowable ().get ())//
321318 .isInstanceOf (PreconditionViolationException .class )//
322319 .hasMessageStartingWith ("Method [()] does not match pattern" );
323320 }
324321
325322 @ Test
326- @ TrackLogRecords
327- void methodResolutionByUniqueIdWithMissingParameters (LogRecordListener listener ) {
323+ void methodResolutionByUniqueIdWithMissingParameters () {
328324 UniqueId uniqueId = uniqueIdForMethod (getClass (), "methodName" );
329325
330326 resolve (request ().selectors (selectUniqueId (uniqueId )));
331327
332328 assertThat (engineDescriptor .getDescendants ()).isEmpty ();
333- LogRecord logRecord = firstWarningLogRecord (listener );
334- assertThat (logRecord .getMessage ()).isEqualTo (
335- "UniqueIdSelector [uniqueId = " + uniqueId + "] could not be resolved." );
336- assertThat (logRecord .getThrown ())//
329+ var result = verifySelectorProcessed (selectUniqueId (uniqueId ));
330+ assertThat (result .getStatus ()).isEqualTo (FAILED );
331+ assertThat (result .getThrowable ().get ())//
337332 .isInstanceOf (PreconditionViolationException .class )//
338333 .hasMessageStartingWith ("Method [methodName] does not match pattern" );
339334 }
340335
341336 @ Test
342- @ TrackLogRecords
343- void methodResolutionByUniqueIdWithBogusParameters (LogRecordListener listener ) {
337+ void methodResolutionByUniqueIdWithBogusParameters () {
344338 UniqueId uniqueId = uniqueIdForMethod (getClass (), "methodName(java.lang.String, junit.foo.Enigma)" );
345339
346340 resolve (request ().selectors (selectUniqueId (uniqueId )));
347341
348342 assertTrue (engineDescriptor .getDescendants ().isEmpty ());
349- LogRecord logRecord = firstWarningLogRecord (listener );
350- assertThat (logRecord .getMessage ()).isEqualTo (
351- "UniqueIdSelector [uniqueId = " + uniqueId + "] could not be resolved." );
352- assertThat (logRecord .getThrown ())//
343+ var result = verifySelectorProcessed (selectUniqueId (uniqueId ));
344+ assertThat (result .getStatus ()).isEqualTo (FAILED );
345+ assertThat (result .getThrowable ().get ())//
353346 .isInstanceOf (JUnitException .class )//
354347 .hasMessage ("Failed to load parameter type [%s] for method [%s] in class [%s]." , "junit.foo.Enigma" ,
355348 "methodName" , getClass ().getName ());
@@ -381,8 +374,7 @@ void methodResolutionByUniqueIdFromInheritedClass() {
381374 }
382375
383376 @ Test
384- @ TrackLogRecords
385- void methodResolutionByUniqueIdWithParams (LogRecordListener listener ) {
377+ void methodResolutionByUniqueIdWithParams () {
386378 UniqueIdSelector selector = selectUniqueId (
387379 uniqueIdForMethod (HerTestClass .class , "test7(java.lang.String)" ).toString ());
388380
@@ -396,15 +388,13 @@ void methodResolutionByUniqueIdWithParams(LogRecordListener listener) {
396388 }
397389
398390 @ Test
399- @ TrackLogRecords
400- void resolvingUniqueIdWithWrongParamsResolvesNothing (LogRecordListener listener ) {
391+ void resolvingUniqueIdWithWrongParamsResolvesNothing () {
401392 UniqueId uniqueId = uniqueIdForMethod (HerTestClass .class , "test7(java.math.BigDecimal)" );
402393
403394 resolve (request ().selectors (selectUniqueId (uniqueId )));
404395
405396 assertTrue (engineDescriptor .getDescendants ().isEmpty ());
406- assertThat (firstWarningLogRecord (listener ).getMessage ())//
407- .isEqualTo ("UniqueIdSelector [uniqueId = " + uniqueId + "] could not be resolved." );
397+ assertUnresolved (selectUniqueId (uniqueId ));
408398 }
409399
410400 @ Test
@@ -633,8 +623,7 @@ void testTemplateMethodResolutionByUniqueId() {
633623 }
634624
635625 @ Test
636- @ TrackLogRecords
637- void resolvingDynamicTestByUniqueIdResolvesUpToParentTestFactory (LogRecordListener listener ) {
626+ void resolvingDynamicTestByUniqueIdResolvesUpToParentTestFactory () {
638627 Class <?> clazz = MyTestClass .class ;
639628 UniqueId factoryUid = uniqueIdForTestFactoryMethod (clazz , "dynamicTest()" );
640629 UniqueId dynamicTestUid = factoryUid .append (DYNAMIC_TEST_SEGMENT_TYPE , "#1" );
@@ -651,12 +640,11 @@ void resolvingDynamicTestByUniqueIdResolvesUpToParentTestFactory(LogRecordListen
651640 assertThat (dynamicDescendantFilter .test (dynamicTestUid )).isTrue ();
652641 assertThat (dynamicDescendantFilter .test (differentDynamicTestUid )).isFalse ();
653642
654- assertZeroLogRecords ( listener );
643+ assertAllSelectorsResolved ( );
655644 }
656645
657646 @ Test
658- @ TrackLogRecords
659- void resolvingDynamicContainerByUniqueIdResolvesUpToParentTestFactory (LogRecordListener listener ) {
647+ void resolvingDynamicContainerByUniqueIdResolvesUpToParentTestFactory () {
660648 Class <?> clazz = MyTestClass .class ;
661649 UniqueId factoryUid = uniqueIdForTestFactoryMethod (clazz , "dynamicTest()" );
662650 UniqueId dynamicContainerUid = factoryUid .append (DYNAMIC_CONTAINER_SEGMENT_TYPE , "#1" );
@@ -676,7 +664,7 @@ void resolvingDynamicContainerByUniqueIdResolvesUpToParentTestFactory(LogRecordL
676664 assertThat (dynamicDescendantFilter .test (differentDynamicContainerUid )).isFalse ();
677665 assertThat (dynamicDescendantFilter .test (differentDynamicTestUid )).isFalse ();
678666
679- assertZeroLogRecords ( listener );
667+ assertAllSelectorsResolved ( );
680668 }
681669
682670 @ Test
@@ -765,18 +753,31 @@ private List<UniqueId> uniqueIds() {
765753 return engineDescriptor .getDescendants ().stream ().map (TestDescriptor ::getUniqueId ).collect (toList ());
766754 }
767755
768- private void assertZeroLogRecords (LogRecordListener listener ) {
769- assertThat (listener .stream (EngineDiscoveryRequestResolver .class )).isEmpty ();
756+ private LauncherDiscoveryRequestBuilder request () {
757+ return LauncherDiscoveryRequestBuilder .request () //
758+ .configurationParameter (DEFAULT_DISCOVERY_LISTENER_CONFIGURATION_PROPERTY_NAME , "logging" ) //
759+ .listeners (discoveryListener );
770760 }
771761
772- private LogRecord firstWarningLogRecord (LogRecordListener listener ) throws AssertionError {
773- return listener .stream (EngineDiscoveryRequestResolver .class , Level .WARNING ).findFirst ().orElseThrow (
774- () -> new AssertionError ("Failed to find warning log record" ));
762+ private void assertAllSelectorsResolved () {
763+ ArgumentCaptor <SelectorResolutionResult > resultCaptor = ArgumentCaptor .forClass (SelectorResolutionResult .class );
764+ verify (discoveryListener ).selectorProcessed (eq (UniqueId .forEngine ("junit-jupiter" )), any (),
765+ resultCaptor .capture ());
766+ assertThat (resultCaptor .getAllValues ()) //
767+ .flatExtracting (SelectorResolutionResult ::getStatus ) //
768+ .allMatch (Predicate .isEqual (RESOLVED ));
775769 }
776770
777- private LogRecord firstDebugLogRecord (LogRecordListener listener ) throws AssertionError {
778- return listener .stream (EngineDiscoveryRequestResolver .class , Level .FINE ).findFirst ().orElseThrow (
779- () -> new AssertionError ("Failed to find debug log record" ));
771+ private void assertUnresolved (DiscoverySelector selector ) {
772+ var result = verifySelectorProcessed (selector );
773+ assertThat (result .getStatus ()).isEqualTo (UNRESOLVED );
774+ }
775+
776+ private SelectorResolutionResult verifySelectorProcessed (DiscoverySelector selector ) {
777+ ArgumentCaptor <SelectorResolutionResult > resultCaptor = ArgumentCaptor .forClass (SelectorResolutionResult .class );
778+ verify (discoveryListener ).selectorProcessed (eq (UniqueId .forEngine ("junit-jupiter" )), eq (selector ),
779+ resultCaptor .capture ());
780+ return resultCaptor .getValue ();
780781 }
781782
782783}
0 commit comments