Java Spring:如何Mock@Autowired对象内部的方法?
Spring环境中Mock同一类内部方法的解决方案
你碰到的异常原因很明确:@Autowired注入的是Spring容器管理的真实Bean实例,而非Mockito的Mock/Spy对象,所以不能直接用doReturn().when()这类语法来Stub方法。下面提供几种可行的解决方式:
方案一:用@Spy部分Mock真实Bean
通过@Spy包装Spring注入的真实Bean,既能保留大部分方法的原有逻辑,又能单独Stub指定方法。
修改测试类代码:
@SpringJUnitConfig(classes = SomeService.class) public class SomeServiceTests { @Spy @Autowired SomeService someService; @Test void method1Test() { // 让method2直接返回100,不执行真实逻辑 doReturn(100).when(someService).method2(); someService.method1(); // 这里写你的断言逻辑 } }
⚠️ 注意:使用Spy时必须用doReturn().when()的写法,不能用when(someService.method2()).thenReturn()——后者会先执行一次真实的method2,达不到Stub的目的。
方案二:手动创建Mock对象并指定真实方法执行
如果你的测试不需要依赖Spring上下文的其他组件,可以直接用Mockito创建Mock对象,同时指定method1执行真实逻辑:
public class SomeServiceTests { @Test void method1Test() { // 创建SomeService的Mock实例 SomeService someService = Mockito.mock(SomeService.class); // 让method1执行真实逻辑 doCallRealMethod().when(someService).method1(); // Stub method2返回100 doReturn(100).when(someService).method2(); someService.method1(); // 断言逻辑 } }
这种方式不需要启动Spring测试上下文,执行速度更快,适合依赖简单的业务类测试。
方案三:用@MockBean替换Spring容器中的Bean
如果你的测试需要依赖其他Spring组件(比如SomeService里还有其他@Autowired的依赖),可以用@MockBean替换容器中的SomeService为Mock对象,再指定method1执行真实逻辑:
@SpringJUnitConfig(classes = SomeService.class) public class SomeServiceTests { @MockBean SomeService someService; @Test void method1Test() { // 指定method1执行真实逻辑 doCallRealMethod().when(someService).method1(); // Stub method2返回100 doReturn(100).when(someService).method2(); someService.method1(); // 断言逻辑 } }
@MockBean会自动替换Spring容器中的对应Bean,确保其他依赖的组件能正常注入。
内容的提问来源于stack exchange,提问作者sainadh
相关产品推荐
相关产品推荐

