为何用@InjectMocks搭配Spring Bean而非@Resource+@MockBean组合?
@InjectMocks+@Mock 与 @Resource+@MockBean 的区别
问题背景
原Service类代码:
@Service public class StudentService { private PenService pen; public StudentService(PenService pen) { this.pen = pen; } }
现有一种测试类配置方式:
public class test { @InjectMocks StudentService student; @Mock PenService pen; @Test public void someTest() { // some code } }
疑问:为何不采用下面这种Spring注解的测试类配置?
public class test { @Resource StudentService student; @MockBean PenService pen; @Test public void someTest() { // some code } }
该配置看似更合理,那么在Spring初始化上下文中,@InjectMocks+@Mock组合与@Resource+@MockBean组合有何区别?
核心区别解析
1. 所属框架与运行环境不同
@Mock和@InjectMocks是Mockito框架的注解,完全不依赖Spring容器。测试时不会启动Spring上下文,直接通过Mockito创建Mock对象并注入到目标类,属于纯单元测试,执行速度极快。@MockBean和@Resource是Spring Test框架的注解,必须启动Spring上下文才能生效。@MockBean会把Mock对象注册到Spring容器,替换原有同类型Bean;@Resource从容器中获取装配好的实例,属于集成/半集成测试,启动上下文会有性能开销。
2. 对象创建与注入逻辑不同
@InjectMocks逻辑:Mockito直接创建StudentService实例(不走Spring Bean生命周期),然后把@Mock标注的PenService通过构造方法、Setter或字段注入进去,全程和Spring容器无关。@Resource+@MockBean逻辑:Spring先启动上下文,注册@MockBean生成的PenServiceMock对象;接着按正常流程实例化StudentService(构造方法注入时从容器取Mock对象);最后@Resource从容器取出装配好的StudentService。
3. 使用场景差异
- 用
@InjectMocks+@Mock:适合只测试StudentService自身业务逻辑的场景,不需要Spring的AOP、事务等特性,追求测试速度,专注单元级逻辑验证。 - 用
@Resource+@MockBean:适合需要Spring上下文支持的场景,比如StudentService用到了Spring切面、事务,或者需要和其他Spring Bean协作,但要Mock掉某个依赖(如PenService)的情况。
4. 对原Bean的影响不同
@Mock的对象仅存在于当前测试类的Mockito上下文,和Spring容器无关,不会影响任何Spring Bean。@MockBean会替换Spring容器中的同类型Bean,这个Mock对象在整个测试上下文生效,多测试方法复用或上下文缓存时,Mock会被保留。
内容的提问来源于stack exchange,提问作者work-in-progress
相关产品推荐
相关产品推荐

