Skip to content

Application Context initialized twice during test when exception thrown during initialization #24888

Closed
@QwertGold

Description

@QwertGold

I noticed that when I have a Spring Boot test, and the context fails to initialize, the Banner is printed twice, and I decided to look into why.

// spring-boot-test-autoconfigure 2.3.7.RELEASE
public class SpringBootDependencyInjectionTestExecutionListener extends DependencyInjectionTestExecutionListener {

	@Override
	public void prepareTestInstance(TestContext testContext) throws Exception {
		try {
			super.prepareTestInstance(testContext);
		}
		catch (Exception ex) {
			outputConditionEvaluationReport(testContext);
			throw ex;
		}
	}
.....
}

When an exception is thrown during initialization, outputConditionEvaluationReport(testContext) is called, which eventually leads to the context being initialized a second time inside DefaultCacheAwareContextLoaderDelegate::loadContext.

This is more a nuisance than a bug, as it only happens in test code; the cost is 'just' developer time and build resources.

I this particular case I want to fail fast, so I throw an exception because I know bad things will happen later.
I'm trying to safeguard against less experienced developers, using resources outside the intended lifecycle. During tests we automatically create external resources in an early lifecycle phase, these resources may only be accessed during later phases, and after the application is started. If a developer violate this rule, and tries to access a resource during bean construction or in an earlier lifecycle, I can detect it, and throw an IlligealStateException. If I don't do this I will get an exception later from the resource Api, and it can be hard for junior developers to identify that they have violated the resource lifecycle, if they get a 404/500 error from a HttpClient.

One possible solution, is to have an AbortTestContextInitializationException, that you could throw, if you decide that the TestContext is in a state where it does not make sense to continue executing, and there is no point in trying to generate the ConditionEvaluationReport. Ideally the failure of the initialization would be cached, so other tests using the same context would fail immediately instead of using build resources , trying to create the context twice for every test.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions