0
votes

I updated to Spring boot 2.1 from Spring 2.0 and my service test failed.

My test structure:

com
  ...
    service
      ServiceTest.java
    web
      ControllerTest.java

ServiceTest.java:

@ExtendWith(SpringExtension.class)
@DataJpaTest
public class ServiceTest {

    @Autowired
    private OtherService otherService;

    ...

}

ControllerTest.java:

@ExtendWith(SpringExtension.class)
@WebMvcTest(secure = false)
@Import(WebMvcConfig.class)
@SuppressWarnings("Duplicates")
public class GroupControllerTest {

    @Configuration
    static class Config {
        @Bean
        public Controller controller() {
            return new Controller();
        }
    }
}

During ServiceTest I get error:

Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'controller' defined in class path resource [com/.../web/ControllerTest$Config.class]

How can spring get Config for ServiceTest from inner package-private class of GroupControllerTest? It's weird! Why does it scan sibling directory for config?

1

1 Answers

1
votes

That is the expected behavior in the Spring TestContext Framework. If you don't explicitly specify which @Configuration class (or classes) to use, Spring will look for a static nested one in the current test class.

The following is an excerpt from the Testing chapter of the Spring Reference Manual.

If you omit the classes attribute from the @ContextConfiguration annotation, the TestContext framework tries to detect the presence of default configuration classes. Specifically, AnnotationConfigContextLoader and AnnotationConfigWebContextLoader detect all static nested classes of the test class that meet the requirements for configuration class implementations, as specified in the @Configuration javadoc. Note that the name of the configuration class is arbitrary. In addition, a test class can contain more than one static nested configuration class if desired.

Since you're using Spring Boot, you should annotate your test class with @SpringBootTest in order to have Spring Boot find your @Configuration class(es).