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

Mockito Mock对象无法注入Service类的问题排查

解决SpringBootTest中Mock对象未注入到Spring Bean的问题

你的问题核心是测试同时混用了Spring集成测试和Mockito单元测试机制,导致ParentService依赖的是Spring容器初始化的真实ChildService实例,而非你定义的Mock实例,两者不是同一个对象,所以Mock的响应不会生效。

下面给出两种可行的解决方案:

方案一:改为纯Mockito单元测试(无需启动Spring容器)

如果你的测试只需要验证ParentService的业务逻辑,不需要依赖Spring容器的其他组件,完全可以用纯Mockito测试,不需要启动Spring:

@ExtendWith(MockitoExtension.class)
public class ParentServiceTest {

    @InjectMocks
    private ParentService parentService;

    @Mock
    private ChildService childService;

    @BeforeEach
    public void init(){
        Mockito.doReturn(otherDto).when(childService).getResponse(Mockito.any(String.class), Mockito.any(DTO.class));
    }

    @Test
    public void createAnswerTEST_Successful(){
        OtherDTO otherDto = parentService.doSomething(someString, dto);
        // 这里添加你的断言逻辑,比如验证返回值是否符合预期
    }
}

说明

  • 去掉@SpringBootTest、@Testcontainers、@ActiveProfiles这些启动Spring容器的注解
  • @InjectMocks会让Mockito自动创建ParentService实例,并将你定义的Mock ChildService注入进去
  • 不需要MockitoAnnotations.openMocks(this),因为@ExtendWith(MockitoExtension.class)已经帮你初始化了Mock对象

方案二:保留Spring集成测试,用@MockBean替换容器中的Bean

如果必须保留SpringBootTest(比如需要依赖其他Spring组件、测试容器等),用@MockBean代替@Mock,它会自动替换Spring容器中的ChildService实例:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Testcontainers
@ActiveProfiles("test")
public class ParentServiceTest {

    @Autowired
    private ParentService parentService;

    @MockBean
    private ChildService childService;

    @BeforeEach
    public void init(){
        Mockito.doReturn(otherDto).when(childService).getResponse(Mockito.any(String.class), Mockito.any(DTO.class));
    }

    @Test
    public void createAnswerTEST_Successful(){
        OtherDTO otherDto = parentService.doSomething(someString, dto);
        // 添加断言逻辑
    }
}

说明

  • @MockBean是Spring提供的注解,会将你定义的Mock实例注册到Spring容器中,替换原本的ChildService Bean
  • 不需要@InjectMocks和MockitoAnnotations.openMocks(this),Spring会自动将Mock的ChildService注入到ParentService中
  • 此时ParentService和ChildService的实例都来自Spring容器,是同一个依赖关系

为什么原来的写法失效?

你之前同时用@SpringBootTest和@Mock/@InjectMocks:

  1. @SpringBootTest启动Spring容器,初始化了ParentService和真实的ChildService
  2. @Mock创建了一个独立的ChildService Mock实例,但这个实例不在Spring容器里
  3. @InjectMocks试图给测试类中的parentService注入Mock,但测试类中的parentService是Spring容器的实例,Mockito无法修改Spring容器内Bean的依赖,导致ParentService依然使用真实的ChildService

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 15:52:28