You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JUnit与Mockito测试中@InjectMocks和@Autowired的适用场景及差异

@InjectMocks vs @Autowired 在JUnit/Mockito测试中的区别与适用场景

一、各自适用场景

@InjectMocks

  • 纯Mockito单元测试:当你只需要聚焦被测类的核心逻辑,想隔离外部依赖(用@Mock/@Spy创建模拟对象),完全不需要启动Spring上下文时,用这个注解最适合。比如测试一个Service类,只需要Mock它依赖的Dao,不用管Spring的Bean管理,快速编写轻量单元测试。
  • 非Spring管理的被测类:如果被测类本身不是Spring Bean,或者你不想让Spring来创建它的实例,@InjectMocks会直接通过反射实例化被测类,并自动把当前测试类里的Mock/Spy实例注入进去。

@Autowired

  • Spring集成测试:当测试需要验证组件间的协作逻辑,或者依赖Spring的特性(比如事务、AOP、配置属性),必须加载Spring上下文时,用@Autowired从容器中获取被测类的实例。
  • 需要真实依赖的测试:如果你的测试需要使用真实的Spring组件(比如真实的Dao操作数据库),@Autowired会帮你取出容器中已经装配好完整依赖的实例;如果需要替换部分依赖为Mock,配合@MockBean即可。

二、在被测类上使用的核心区别

1. 实例创建主体

  • @InjectMocks:由Mockito直接创建被测类实例,完全脱离Spring容器,不需要任何Spring相关的配置或上下文启动。
  • @Autowired:由Spring容器创建并管理被测类实例,实例是Spring上下文里的标准Bean,依赖的注入也由Spring容器负责。

2. 依赖来源

  • @InjectMocks:只能注入当前测试类中用@Mock、@Spy注解定义的模拟对象,不会从Spring容器获取任何依赖。
  • @Autowired:依赖完全来自Spring容器,既可以是真实的业务Bean,也可以是用@MockBean替换后的模拟Bean(需要Spring Boot Test等支持)。

3. 测试类型适配

  • @InjectMocks:专门为单元测试设计,测试速度快,专注于被测类自身的逻辑验证,隔离外部环境。
  • @Autowired:主要用于集成测试,验证多个组件之间的交互逻辑,需要加载Spring上下文,测试速度相对较慢。

4. 注入规则

  • @InjectMocks:注入优先级为「构造方法注入 > Setter方法注入 > 字段注入」,Mockito会自动尝试匹配类型一致的Mock/Spy实例。
  • @Autowired:遵循Spring的依赖注入规则,默认按类型匹配,可配合@Qualifier指定名称;Spring 4.3+推荐优先使用构造方法注入,也支持Setter和字段注入。

示例代码

@InjectMocks 单元测试示例

@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
    @Mock
    private UserDao userDao; // 创建Mock依赖

    @InjectMocks
    private UserService userService; // Mockito自动注入userDao到userService

    @Test
    public void testGetUserById() {
        // 给定
        when(userDao.findById(1L)).thenReturn(new User(1L, "张三"));
        // 当
        User result = userService.getUserById(1L);
        // 断言
        assertEquals("张三", result.getName());
    }
}

@Autowired 集成测试示例

@SpringBootTest
public class UserServiceIntegrationTest {
    @Autowired
    private UserService userService; // 从Spring容器获取实例

    @MockBean
    private UserDao userDao; // 替换容器中的UserDao为Mock

    @Test
    public void testGetUserById() {
        // 给定
        when(userDao.findById(2L)).thenReturn(new User(2L, "李四"));
        // 当
        User result = userService.getUserById(2L);
        // 断言
        assertEquals("李四", result.getName());
    }
}

内容的提问来源于stack exchange,提问作者Mukul Maurya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 07:06:32