From 6a09fd6d727fa19dc6e0c63dd5c1c19cabb9bb28 Mon Sep 17 00:00:00 2001 From: Samaresh Kumar Singh Date: Tue, 18 Nov 2025 18:02:48 -0600 Subject: [PATCH 1/2] Add comprehensive tests for ExecutionListenerAdapter Resolves the TODO comment by implementing tests for all adapter methods that were previously untested. This significantly improves test coverage of the ExecutionListenerAdapter class. Tests added: - testDynamicTestRegistered(): Verifies dynamic test registration - testExecutionStarted(): Verifies test execution start notification - testExecutionSkipped(): Verifies test skip notification with reason - testExecutionFinished(): Verifies test execution completion - testFileEntryPublished(): Verifies file entry publication The MockTestExecutionListener was extended to capture all callback invocations, enabling proper verification of each adapter method. All tests follow the existing pattern and verify that: 1. The adapter correctly translates TestDescriptor to TestIdentifier 2. All parameters are properly passed through to the listener 3. The TestPlan is correctly consulted for identifier lookup --- .../core/ExecutionListenerAdapterTests.java | 151 +++++++++++++++++- 1 file changed, 150 insertions(+), 1 deletion(-) diff --git a/platform-tests/src/test/java/org/junit/platform/launcher/core/ExecutionListenerAdapterTests.java b/platform-tests/src/test/java/org/junit/platform/launcher/core/ExecutionListenerAdapterTests.java index 92cd627068ee..af79ebd174ca 100644 --- a/platform-tests/src/test/java/org/junit/platform/launcher/core/ExecutionListenerAdapterTests.java +++ b/platform-tests/src/test/java/org/junit/platform/launcher/core/ExecutionListenerAdapterTests.java @@ -20,7 +20,9 @@ import org.junit.jupiter.api.Test; import org.junit.platform.commons.util.ReflectionUtils; import org.junit.platform.engine.TestDescriptor; +import org.junit.platform.engine.TestExecutionResult; import org.junit.platform.engine.UniqueId; +import org.junit.platform.engine.reporting.FileEntry; import org.junit.platform.engine.reporting.ReportEntry; import org.junit.platform.engine.support.descriptor.DemoMethodTestDescriptor; import org.junit.platform.launcher.TestExecutionListener; @@ -30,7 +32,6 @@ /** * @since 1.0 */ -// TODO Test other adapter methods. class ExecutionListenerAdapterTests { @Test @@ -54,6 +55,102 @@ void testReportingEntryPublished() { assertThat(testExecutionListener.testIdentifier).isEqualTo(testIdentifier); } + @Test + void testDynamicTestRegistered() { + var testDescriptor = getSampleMethodTestDescriptor(); + + var discoveryResult = new LauncherDiscoveryResult( + Map.of(mock(), EngineResultInfo.completed(testDescriptor, DiscoveryIssueNotifier.NO_ISSUES)), mock(), + dummyOutputDirectoryCreator()); + var testPlan = InternalTestPlan.from(discoveryResult); + + var testExecutionListener = new MockTestExecutionListener(); + var executionListenerAdapter = new ExecutionListenerAdapter(testPlan, testExecutionListener); + + executionListenerAdapter.dynamicTestRegistered(testDescriptor); + + var testIdentifier = testPlan.getTestIdentifier(testDescriptor.getUniqueId()); + assertThat(testExecutionListener.dynamicallyRegisteredIdentifier).isEqualTo(testIdentifier); + } + + @Test + void testExecutionStarted() { + var testDescriptor = getSampleMethodTestDescriptor(); + + var discoveryResult = new LauncherDiscoveryResult( + Map.of(mock(), EngineResultInfo.completed(testDescriptor, DiscoveryIssueNotifier.NO_ISSUES)), mock(), + dummyOutputDirectoryCreator()); + var testPlan = InternalTestPlan.from(discoveryResult); + var testIdentifier = testPlan.getTestIdentifier(testDescriptor.getUniqueId()); + + var testExecutionListener = new MockTestExecutionListener(); + var executionListenerAdapter = new ExecutionListenerAdapter(testPlan, testExecutionListener); + + executionListenerAdapter.executionStarted(testDescriptor); + + assertThat(testExecutionListener.startedIdentifier).isEqualTo(testIdentifier); + } + + @Test + void testExecutionSkipped() { + var testDescriptor = getSampleMethodTestDescriptor(); + + var discoveryResult = new LauncherDiscoveryResult( + Map.of(mock(), EngineResultInfo.completed(testDescriptor, DiscoveryIssueNotifier.NO_ISSUES)), mock(), + dummyOutputDirectoryCreator()); + var testPlan = InternalTestPlan.from(discoveryResult); + var testIdentifier = testPlan.getTestIdentifier(testDescriptor.getUniqueId()); + + var testExecutionListener = new MockTestExecutionListener(); + var executionListenerAdapter = new ExecutionListenerAdapter(testPlan, testExecutionListener); + + var reason = "Test skipped due to condition"; + executionListenerAdapter.executionSkipped(testDescriptor, reason); + + assertThat(testExecutionListener.skippedIdentifier).isEqualTo(testIdentifier); + assertThat(testExecutionListener.skipReason).isEqualTo(reason); + } + + @Test + void testExecutionFinished() { + var testDescriptor = getSampleMethodTestDescriptor(); + + var discoveryResult = new LauncherDiscoveryResult( + Map.of(mock(), EngineResultInfo.completed(testDescriptor, DiscoveryIssueNotifier.NO_ISSUES)), mock(), + dummyOutputDirectoryCreator()); + var testPlan = InternalTestPlan.from(discoveryResult); + var testIdentifier = testPlan.getTestIdentifier(testDescriptor.getUniqueId()); + + var testExecutionListener = new MockTestExecutionListener(); + var executionListenerAdapter = new ExecutionListenerAdapter(testPlan, testExecutionListener); + + var result = mock(TestExecutionResult.class); + executionListenerAdapter.executionFinished(testDescriptor, result); + + assertThat(testExecutionListener.finishedIdentifier).isEqualTo(testIdentifier); + assertThat(testExecutionListener.executionResult).isEqualTo(result); + } + + @Test + void testFileEntryPublished() { + var testDescriptor = getSampleMethodTestDescriptor(); + + var discoveryResult = new LauncherDiscoveryResult( + Map.of(mock(), EngineResultInfo.completed(testDescriptor, DiscoveryIssueNotifier.NO_ISSUES)), mock(), + dummyOutputDirectoryCreator()); + var testPlan = InternalTestPlan.from(discoveryResult); + var testIdentifier = testPlan.getTestIdentifier(testDescriptor.getUniqueId()); + + var testExecutionListener = new MockTestExecutionListener(); + var executionListenerAdapter = new ExecutionListenerAdapter(testPlan, testExecutionListener); + + var fileEntry = mock(FileEntry.class); + executionListenerAdapter.fileEntryPublished(testDescriptor, fileEntry); + + assertThat(testExecutionListener.fileEntryIdentifier).isEqualTo(testIdentifier); + assertThat(testExecutionListener.publishedFileEntry).isEqualTo(fileEntry); + } + private TestDescriptor getSampleMethodTestDescriptor() { var localMethodNamedNothing = ReflectionUtils.findMethod(this.getClass(), "nothing", new Class[0]).orElseThrow(); @@ -72,12 +169,64 @@ static class MockTestExecutionListener implements TestExecutionListener { @Nullable public ReportEntry entry; + @Nullable + public TestIdentifier dynamicallyRegisteredIdentifier; + + @Nullable + public TestIdentifier startedIdentifier; + + @Nullable + public TestIdentifier skippedIdentifier; + + @Nullable + public String skipReason; + + @Nullable + public TestIdentifier finishedIdentifier; + + @Nullable + public TestExecutionResult executionResult; + + @Nullable + public TestIdentifier fileEntryIdentifier; + + @Nullable + public FileEntry publishedFileEntry; + + @Override + public void dynamicTestRegistered(TestIdentifier testIdentifier) { + this.dynamicallyRegisteredIdentifier = testIdentifier; + } + + @Override + public void executionStarted(TestIdentifier testIdentifier) { + this.startedIdentifier = testIdentifier; + } + + @Override + public void executionSkipped(TestIdentifier testIdentifier, String reason) { + this.skippedIdentifier = testIdentifier; + this.skipReason = reason; + } + + @Override + public void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) { + this.finishedIdentifier = testIdentifier; + this.executionResult = testExecutionResult; + } + @Override public void reportingEntryPublished(TestIdentifier testIdentifier, ReportEntry entry) { this.testIdentifier = testIdentifier; this.entry = entry; } + @Override + public void fileEntryPublished(TestIdentifier testIdentifier, FileEntry fileEntry) { + this.fileEntryIdentifier = testIdentifier; + this.publishedFileEntry = fileEntry; + } + } } From 14e2b73be57702850427b9aacc87afeaecdfe56c Mon Sep 17 00:00:00 2001 From: Samaresh Kumar Singh Date: Fri, 21 Nov 2025 13:22:27 -0600 Subject: [PATCH 2/2] test: refactor ExecutionListenerAdapterTests to use Mockito spy Address reviewer feedback. Signed-off-by: Samaresh Kumar Singh --- .../core/ExecutionListenerAdapterTests.java | 166 +++--------------- 1 file changed, 29 insertions(+), 137 deletions(-) diff --git a/platform-tests/src/test/java/org/junit/platform/launcher/core/ExecutionListenerAdapterTests.java b/platform-tests/src/test/java/org/junit/platform/launcher/core/ExecutionListenerAdapterTests.java index af79ebd174ca..d1f8488c3961 100644 --- a/platform-tests/src/test/java/org/junit/platform/launcher/core/ExecutionListenerAdapterTests.java +++ b/platform-tests/src/test/java/org/junit/platform/launcher/core/ExecutionListenerAdapterTests.java @@ -10,13 +10,14 @@ package org.junit.platform.launcher.core; -import static org.assertj.core.api.Assertions.assertThat; import static org.junit.platform.launcher.core.OutputDirectoryCreators.dummyOutputDirectoryCreator; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; import java.util.Map; -import org.jspecify.annotations.Nullable; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.platform.commons.util.ReflectionUtils; import org.junit.platform.engine.TestDescriptor; @@ -34,121 +35,80 @@ */ class ExecutionListenerAdapterTests { - @Test - void testReportingEntryPublished() { - var testDescriptor = getSampleMethodTestDescriptor(); + private TestDescriptor testDescriptor; + private InternalTestPlan testPlan; + private TestExecutionListener testExecutionListener; + private ExecutionListenerAdapter executionListenerAdapter; + + @BeforeEach + void setUp() { + testDescriptor = getSampleMethodTestDescriptor(); var discoveryResult = new LauncherDiscoveryResult( Map.of(mock(), EngineResultInfo.completed(testDescriptor, DiscoveryIssueNotifier.NO_ISSUES)), mock(), dummyOutputDirectoryCreator()); - var testPlan = InternalTestPlan.from(discoveryResult); - var testIdentifier = testPlan.getTestIdentifier(testDescriptor.getUniqueId()); + testPlan = InternalTestPlan.from(discoveryResult); - //not yet spyable with mockito? -> https://github.com/mockito/mockito/issues/146 - var testExecutionListener = new MockTestExecutionListener(); - var executionListenerAdapter = new ExecutionListenerAdapter(testPlan, testExecutionListener); + testExecutionListener = spy(TestExecutionListener.class); + executionListenerAdapter = new ExecutionListenerAdapter(testPlan, testExecutionListener); + } + @Test + void testReportingEntryPublished() { + var testIdentifier = testPlan.getTestIdentifier(testDescriptor.getUniqueId()); var entry = ReportEntry.from("one", "two"); + executionListenerAdapter.reportingEntryPublished(testDescriptor, entry); - assertThat(testExecutionListener.entry).isEqualTo(entry); - assertThat(testExecutionListener.testIdentifier).isEqualTo(testIdentifier); + verify(testExecutionListener).reportingEntryPublished(testIdentifier, entry); } @Test void testDynamicTestRegistered() { - var testDescriptor = getSampleMethodTestDescriptor(); - - var discoveryResult = new LauncherDiscoveryResult( - Map.of(mock(), EngineResultInfo.completed(testDescriptor, DiscoveryIssueNotifier.NO_ISSUES)), mock(), - dummyOutputDirectoryCreator()); - var testPlan = InternalTestPlan.from(discoveryResult); - - var testExecutionListener = new MockTestExecutionListener(); - var executionListenerAdapter = new ExecutionListenerAdapter(testPlan, testExecutionListener); + var testIdentifier = testPlan.getTestIdentifier(testDescriptor.getUniqueId()); executionListenerAdapter.dynamicTestRegistered(testDescriptor); - var testIdentifier = testPlan.getTestIdentifier(testDescriptor.getUniqueId()); - assertThat(testExecutionListener.dynamicallyRegisteredIdentifier).isEqualTo(testIdentifier); + verify(testExecutionListener).dynamicTestRegistered(testIdentifier); } @Test void testExecutionStarted() { - var testDescriptor = getSampleMethodTestDescriptor(); - - var discoveryResult = new LauncherDiscoveryResult( - Map.of(mock(), EngineResultInfo.completed(testDescriptor, DiscoveryIssueNotifier.NO_ISSUES)), mock(), - dummyOutputDirectoryCreator()); - var testPlan = InternalTestPlan.from(discoveryResult); var testIdentifier = testPlan.getTestIdentifier(testDescriptor.getUniqueId()); - var testExecutionListener = new MockTestExecutionListener(); - var executionListenerAdapter = new ExecutionListenerAdapter(testPlan, testExecutionListener); - executionListenerAdapter.executionStarted(testDescriptor); - assertThat(testExecutionListener.startedIdentifier).isEqualTo(testIdentifier); + verify(testExecutionListener).executionStarted(testIdentifier); } @Test void testExecutionSkipped() { - var testDescriptor = getSampleMethodTestDescriptor(); - - var discoveryResult = new LauncherDiscoveryResult( - Map.of(mock(), EngineResultInfo.completed(testDescriptor, DiscoveryIssueNotifier.NO_ISSUES)), mock(), - dummyOutputDirectoryCreator()); - var testPlan = InternalTestPlan.from(discoveryResult); var testIdentifier = testPlan.getTestIdentifier(testDescriptor.getUniqueId()); - - var testExecutionListener = new MockTestExecutionListener(); - var executionListenerAdapter = new ExecutionListenerAdapter(testPlan, testExecutionListener); - var reason = "Test skipped due to condition"; + executionListenerAdapter.executionSkipped(testDescriptor, reason); - assertThat(testExecutionListener.skippedIdentifier).isEqualTo(testIdentifier); - assertThat(testExecutionListener.skipReason).isEqualTo(reason); + verify(testExecutionListener).executionSkipped(testIdentifier, reason); } @Test void testExecutionFinished() { - var testDescriptor = getSampleMethodTestDescriptor(); - - var discoveryResult = new LauncherDiscoveryResult( - Map.of(mock(), EngineResultInfo.completed(testDescriptor, DiscoveryIssueNotifier.NO_ISSUES)), mock(), - dummyOutputDirectoryCreator()); - var testPlan = InternalTestPlan.from(discoveryResult); var testIdentifier = testPlan.getTestIdentifier(testDescriptor.getUniqueId()); - - var testExecutionListener = new MockTestExecutionListener(); - var executionListenerAdapter = new ExecutionListenerAdapter(testPlan, testExecutionListener); - var result = mock(TestExecutionResult.class); + executionListenerAdapter.executionFinished(testDescriptor, result); - assertThat(testExecutionListener.finishedIdentifier).isEqualTo(testIdentifier); - assertThat(testExecutionListener.executionResult).isEqualTo(result); + verify(testExecutionListener).executionFinished(testIdentifier, result); } @Test void testFileEntryPublished() { - var testDescriptor = getSampleMethodTestDescriptor(); - - var discoveryResult = new LauncherDiscoveryResult( - Map.of(mock(), EngineResultInfo.completed(testDescriptor, DiscoveryIssueNotifier.NO_ISSUES)), mock(), - dummyOutputDirectoryCreator()); - var testPlan = InternalTestPlan.from(discoveryResult); var testIdentifier = testPlan.getTestIdentifier(testDescriptor.getUniqueId()); - - var testExecutionListener = new MockTestExecutionListener(); - var executionListenerAdapter = new ExecutionListenerAdapter(testPlan, testExecutionListener); - var fileEntry = mock(FileEntry.class); + executionListenerAdapter.fileEntryPublished(testDescriptor, fileEntry); - assertThat(testExecutionListener.fileEntryIdentifier).isEqualTo(testIdentifier); - assertThat(testExecutionListener.publishedFileEntry).isEqualTo(fileEntry); + verify(testExecutionListener).fileEntryPublished(testIdentifier, fileEntry); } private TestDescriptor getSampleMethodTestDescriptor() { @@ -161,72 +121,4 @@ private TestDescriptor getSampleMethodTestDescriptor() { void nothing() { } - static class MockTestExecutionListener implements TestExecutionListener { - - @Nullable - public TestIdentifier testIdentifier; - - @Nullable - public ReportEntry entry; - - @Nullable - public TestIdentifier dynamicallyRegisteredIdentifier; - - @Nullable - public TestIdentifier startedIdentifier; - - @Nullable - public TestIdentifier skippedIdentifier; - - @Nullable - public String skipReason; - - @Nullable - public TestIdentifier finishedIdentifier; - - @Nullable - public TestExecutionResult executionResult; - - @Nullable - public TestIdentifier fileEntryIdentifier; - - @Nullable - public FileEntry publishedFileEntry; - - @Override - public void dynamicTestRegistered(TestIdentifier testIdentifier) { - this.dynamicallyRegisteredIdentifier = testIdentifier; - } - - @Override - public void executionStarted(TestIdentifier testIdentifier) { - this.startedIdentifier = testIdentifier; - } - - @Override - public void executionSkipped(TestIdentifier testIdentifier, String reason) { - this.skippedIdentifier = testIdentifier; - this.skipReason = reason; - } - - @Override - public void executionFinished(TestIdentifier testIdentifier, TestExecutionResult testExecutionResult) { - this.finishedIdentifier = testIdentifier; - this.executionResult = testExecutionResult; - } - - @Override - public void reportingEntryPublished(TestIdentifier testIdentifier, ReportEntry entry) { - this.testIdentifier = testIdentifier; - this.entry = entry; - } - - @Override - public void fileEntryPublished(TestIdentifier testIdentifier, FileEntry fileEntry) { - this.fileEntryIdentifier = testIdentifier; - this.publishedFileEntry = fileEntry; - } - - } - }