Skip to content

@RecordApplicationEvents doesn't work on threads spawned before the test execution #31079

Closed as not planned
@romainmoreau

Description

@romainmoreau

The issue with ApplicationEventsHolder and its InheritableThreadLocal solution implemented in #30020 is that it only works if the thread is spawned in the test method like in the unit test JUnit4ApplicationEventsAsyncIntegrationTests but if the thread is spawned before registerApplicationEvents is called on the main/parent thread (for instance during application context creation), then every application event emitted during the test on this spawned thread will be ignored.

Here's a slightly modified version of JUnit4ApplicationEventsAsyncIntegrationTests that reproduce the issue:

@SpringBootTest
@RecordApplicationEvents
public class JUnit4ApplicationEventsAsyncIntegrationTests {
	@Autowired
	ApplicationEvents applicationEvents;

	@Autowired
	Thread thread;

	@Test
	public void asyncPublication() throws InterruptedException {
		thread.start();
		thread.join();

		assertThat(this.applicationEvents.stream(CustomEvent.class)).singleElement()
				.extracting(CustomEvent::getMessage, InstanceOfAssertFactories.STRING).isEqualTo("async");
	}

	@Configuration
	static class Config {
		@Autowired
		ApplicationContext context;

		@Bean
		Thread thread() {
			return new Thread(() -> context.publishEvent(new CustomEvent("async")));
		}
	}

	static class CustomEvent extends ApplicationEvent {
		private static final long serialVersionUID = 1L;

		private final String message;

		CustomEvent(String message) {
			super(message);
			this.message = message;
		}

		String getMessage() {
			return message;
		}
	}
}

Metadata

Metadata

Assignees

Labels

in: testIssues in the test modulestatus: declinedA suggestion or change that we don't feel we should currently apply

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions