Apparently Spring creates another ApplicationContext
when a @Nested
class has custom configuration, e.g. @TestPropertySource
. In that case two application contexts exist, one AnnotationConfigServletWebServerApplicationContext
as usual and another one used in the scope of the nested class with the type of GenericWebApplicationContext
.
The problem is, when a MockMvc
variable is defined and autowired at the base class level, i.e. outside of the nested class, but then used in the nested class, this variable will "use" the ApplicationContext
of the base class.
My solution is to simply define and autowire a MockMvc
variable in the nested class as well, however it took me some time to understand the issue and I wanted to make sure that I'm not missing something and using a wrong approach.
Here is an example
@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class DemoControllerTests
{
@Autowired
private MockMvc mockMvc;
@Nested
class NestedClassWithoutCustomConfiguration
{
// works as expected; mockMvc and nested class use same application context of type
// "AnnotationConfigServletWebServerApplicationContext"
}
@Nested
@TestPropertySource(properties = "foo=bar")
class NestedClassWithCustomConfiguration
{
// does not work as expected; a new applicationContext of type "GenericWebApplicationContext" is created;
// however mockMvc is using "base" applicationContext of type "AnnotationConfigServletWebServerApplicationContext"
}
}