Spring 在测试期间从包私有类获取配置
Posted
技术标签:
【中文标题】Spring 在测试期间从包私有类获取配置【英文标题】:Spring gets config from package-private class during test 【发布时间】:2019-06-19 11:26:40 【问题描述】:我从 Spring 2.0 更新到 Spring boot 2.1 并且我的服务测试失败。
我的测试结构:
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();
在 ServiceTest 期间出现错误:
原因: org.springframework.beans.factory.support.BeanDefinitionOverrideException: 类路径中定义的名称为“控制器”的无效 bean 定义 资源 [com/.../web/ControllerTest$Config.class]
spring 如何从 GroupControllerTest 的内部包私有类中获取 ServiceTest 的配置? 有点奇怪!为什么要扫描兄弟目录进行配置?
【问题讨论】:
【参考方案1】:这是 Spring TestContext Framework 中的预期行为。如果您没有明确指定要使用哪个@Configuration
类(或多个类),Spring 将在当前测试类中查找静态嵌套类。
以下是Spring参考手册Testing chapter的摘录。
如果您从
@ContextConfiguration
注释中省略 classes 属性,TestContext 框架会尝试检测默认配置类的存在。具体来说,AnnotationConfigContextLoader
和AnnotationConfigWebContextLoader
检测测试类的所有静态嵌套类,这些类满足@Configuration
javadoc 中指定的配置类实现的要求。请注意,配置类的名称是任意的。此外,如果需要,一个测试类可以包含多个静态嵌套配置类。
由于您使用的是 Spring Boot,因此您应该使用 @SpringBootTest
注释您的测试类,以便让 Spring Boot 找到您的 @Configuration
类。
【讨论】:
我明白这一点,但是通过 spring 从其他类的静态内部类获取配置,而不是当前的? 核心 Spring 中的 Spring TestContext Framework 不会扫描除当前测试类之外的任何类中的静态嵌套类。 因此,必须有其他东西通过组件扫描拉入该类。也许是您的@Configuration
类或 Spring Boot 之一。
如果你用@SpringBootTest
注释ServiceTest
会发生什么?
感谢您对组件扫描的看法。我有 @SpringBootApplication 和 @ComponentScan(...) 扫描我所有的包,但我没有意识到它也会影响测试包。所以我需要重构)以上是关于Spring 在测试期间从包私有类获取配置的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 自动装配配置类进入 Junit 测试
获取SPRING 代理对象的真实实例,可以反射私有方法,便于测试