Skip to content

Configuration from enclosing class not discovered for @Nested test class when enclosing class is not annotated with @ContextConfiguration #31456

Open
@sbrannen

Description

@sbrannen

Overview

Given the following application and test classes, the @Nested test class fails due to getMessage() returning "Hello!" instead of "Mocked!" resulting from the fact that the static nested @TestConfiguration class is only discovered for the top-level enclosing test class.

Specifically, the MergedContextConfiguration for TestConfigurationNestedTests contains classes = [example.Application, example.TestConfigurationNestedTests.TestConfig]; whereas, the MergedContextConfiguration for InnerTests contains only classes = [example.Application].

A cursory search for @TestConfiguration reveals that SpringBootTestContextBootstrapper.containsNonTestComponent(...) uses the INHERITED_ANNOTATIONS search strategy for merged annotations. Instead, it should likely need to make use of TestContextAnnotationUtils in order to provide proper support for @NestedTestConfiguration semantics (perhaps analogous to the use of TestContextAnnotationUtils.searchEnclosingClass(...) in MockitoContextCustomizerFactory.parseDefinitions(...)).

As a side note, if you uncomment @Import(TestConfig.class) both test classes will pass.

package example;

// imports...

@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

	@Service
	public static class GreetingService {
		public String getMessage() {
			return "Hello!";
		}
	}
}
package example;

// imports...

@SpringBootTest
// @Import(TestConfig.class)
class TestConfigurationNestedTests {

	@Test
	void test(@Autowired GreetingService greetingService) {
		assertThat(greetingService.getMessage()).isEqualTo("Mocked!");
	}

	@Nested
	class InnerTests {

		@Test
		void test(@Autowired GreetingService greetingService) {
			assertThat(greetingService.getMessage()).isEqualTo("Mocked!");
		}
	}

	@TestConfiguration
	static class TestConfig {

		@MockBean
		GreetingService greetingService;

		@BeforeTestMethod
		void configureMock(BeforeTestMethodEvent event) {
			when(this.greetingService.getMessage()).thenReturn("Mocked!");
		}
	}

}

Related Issues and Commits

Metadata

Metadata

Assignees

Labels

in: testIssues in the test modulestatus: pending-design-workNeeds design work before any code can be developedtype: bugA general bug

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions