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:
@SpringBootTest启动Spring容器,初始化了ParentService和真实的ChildService@Mock创建了一个独立的ChildService Mock实例,但这个实例不在Spring容器里@InjectMocks试图给测试类中的parentService注入Mock,但测试类中的parentService是Spring容器的实例,Mockito无法修改Spring容器内Bean的依赖,导致ParentService依然使用真实的ChildService
内容的提问来源于stack exchange,提问作者FJ97
相关产品推荐
相关产品推荐

