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

Spring Controller单元测试无法自动装配所需Bean问题

解决Spring Controller单元测试中Mock服务注入为null的问题

嘿,这个问题我太熟啦!你之所以碰到myService为null的情况,核心原因就是你直接new出来的MyController实例,压根没和你Mock好的myService关联上,控制器里的@Autowired字段自然找不到依赖啦~

下面给你几种简单好用的解决方案,挑你顺手的来:

方案一:用Mockito的@InjectMocks自动注入(最推荐)

Mockito专门提供了@InjectMocks注解,能自动把所有用@Mock标注的对象,注入到目标类的对应字段里。修改你的测试代码就行:

@RunWith(MockitoJUnitRunner.class)
public class TestManageDevices {
    private MockMvc mockMvc;
    @Mock
    MyService myService;
    @InjectMocks // 关键:让Mockito自动把mock的myService注入到这个控制器实例
    private MyController myController;

    @Before
    public void setUp() {
        // 用注入好依赖的myController来构建MockMvc
        mockMvc = MockMvcBuilders.standaloneSetup(myController)
                .build();
    }

    // 你的测试方法保持不变...
}

这个注解会自动匹配字段类型或名称,不管你控制器里用的是@Autowired、@Resource还是构造注入,都能搞定。

方案二:手动注入依赖(适合不想用注解的场景)

如果你不想用@InjectMocks,也可以手动给控制器的服务字段赋值:

  • 如果你的MyController有setMyService方法,直接调用就行:
@Before
public void setUp() {
    MyController myController = new MyController();
    myController.setMyService(myService); // 手动把mock的服务塞进去
    mockMvc = MockMvcBuilders.standaloneSetup(myController)
            .build();
}
  • 如果没有setter,也可以用反射硬塞(应急用,不推荐长期这么干):
@Before
public void setUp() throws NoSuchFieldException, IllegalAccessException {
    MyController myController = new MyController();
    Field serviceField = MyController.class.getDeclaredField("myService");
    serviceField.setAccessible(true); // 突破私有字段限制
    serviceField.set(myController, myService);
    mockMvc = MockMvcBuilders.standaloneSetup(myController)
            .build();
}

方案三:用Spring Boot Test的@WebMvcTest(适合Spring Boot项目)

如果你的项目是Spring Boot,也可以用@WebMvcTest注解,让Spring帮你管理上下文和依赖注入:

@WebMvcTest(MyController.class)
public class TestManageDevices {
    @Autowired
    private MockMvc mockMvc;
    @MockBean // 把MyService的Mock实例注册到Spring上下文
    private MyService myService;

    @Test
    public void shouldPass() throws Exception {
        // 测试逻辑完全不变...
    }
}

这种方式更贴近真实运行环境,Spring会自动处理控制器的依赖,你甚至不用手动构建MockMvc。

最后提个小建议

现在更推荐用构造注入代替字段注入(就是在控制器的构造方法里接收MyService,而不是用@Autowired标注字段),这样不仅能避免null问题,还能让代码更易测试、更符合依赖注入的原则哦~

内容的提问来源于stack exchange,提问作者Ravat Tailor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:15:16