-
Notifications
You must be signed in to change notification settings - Fork 38.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Configuration from enclosing class not discovered for @Nested
test class when enclosing class is not annotated with @ContextConfiguration
#31456
Comments
Actually, if you annotate |
Looks similar to spring-projects/spring-boot#33317, potentially even a duplicate. |
Thanks for pointing out spring-projects/spring-boot#33317, @vpavic. It's certainly related, but I wouldn't consider it a duplicate since different solutions will be applied in different places to address the two sets of issues. |
uncommenting the @import(TestConfig.class) annotation on the top-level test class will work around the issue. Additionally, you could consider refactoring your test code to avoid the use of nested @TestConfiguration classes, if possible. For example, you could move the TestConfig class to the top-level test class and use @beforeeach and @AfterEach methods to set up and tear down the mocked beans. |
Thanks, @sbrannen. Boot calls |
That's correct. That utility method only supports finding static nested
As I mentioned in this issue's description, I believe you will need to make use of The following two test classes demonstrate the difference in behavior between Spring Framework and Spring Boot. @SpringJUnitConfig
class SpringFrameworkNestedTests {
@Test
void test(@Autowired String foo) {
assertThat(foo).isEqualTo("bar");
}
@Nested
class InnerTests {
@Test
void test(@Autowired String foo) {
assertThat(foo).isEqualTo("bar");
}
}
@Configuration
static class TestConfig {
@Bean
String foo() {
return "bar";
}
}
} @SpringBootTest
class SpringBootNestedTests {
@Test
void test(@Autowired String foo) {
assertThat(foo).isEqualTo("bar");
}
@Nested
class InnerTests {
@Test
void test(@Autowired String foo) {
assertThat(foo).isEqualTo("bar");
}
}
@Configuration
static class TestConfig {
@Bean
String foo() {
return "bar";
}
}
}
Thus, the difference appears to be in the behavior of |
I think we agree on that. Andy wrote:
So. Is there an API we could use? |
If you run into any stumbling blocks, let me know, and I'll see if I can help. |
@TestConfiguration
from enclosing class not discovered for @Nested
test class
This looks like a bug in Spring Framework to me. The difference in behavior described in this comment isn't a difference between Spring Boot and Spring Framework but a difference in Spring Framework's behavior with and without package com.example;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
@SpringJUnitConfig
class SpringJUnitConfigNestedTests {
@Test
void test(@Autowired String foo) {
assertThat(foo).isEqualTo("bar");
}
@Nested
class InnerTests {
@Test
void test(@Autowired String foo) {
assertThat(foo).isEqualTo("bar");
}
}
@Configuration
static class TestConfig {
@Bean
String foo() {
return "bar";
}
}
} package com.example;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
class SpringExtensionNestedTests {
@Test
void test(@Autowired String foo) {
assertThat(foo).isEqualTo("bar");
}
@Nested
class InnerTests {
@Test
void test(@Autowired String foo) {
assertThat(foo).isEqualTo("bar");
}
}
@Configuration
static class TestConfig {
@Bean
String foo() {
return "bar";
}
}
}
Without |
@Nested
test class when enclosing class is not annotated with @ContextConfiguration
Given the following application and test classes, the
@Nested
test class fails due togetMessage()
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
forTestConfigurationNestedTests
containsclasses = [example.Application, example.TestConfigurationNestedTests.TestConfig]
; whereas, theMergedContextConfiguration
forInnerTests
contains onlyclasses = [example.Application]
.A cursory search for
@TestConfiguration
reveals thatSpringBootTestContextBootstrapper.containsNonTestComponent(...)
uses theINHERITED_ANNOTATIONS
search strategy for merged annotations. Instead, it should likely need to make use ofTestContextAnnotationUtils
in order to provide proper support for@NestedTestConfiguration
semantics (perhaps analogous to the use ofTestContextAnnotationUtils.searchEnclosingClass(...)
inMockitoContextCustomizerFactory.parseDefinitions(...)
).As a side note, if you uncomment
@Import(TestConfig.class)
both test classes will pass.The text was updated successfully, but these errors were encountered: