Mockito:如何Mock另一个方法内部调用的方法?
如何正确Mock内部调用的
b.getBName(id)方法 首先得明确核心:要让a.getAName()调用时跳过真实的b.getBName(id)执行,关键是确保A类里依赖的B对象是Mock实例,而非真实对象,同时给这个Mock实例设置好预期返回行为。
下面结合最常用的Mockito框架,分场景给出具体解决方案:
场景1:A类通过构造器注入B对象
如果你的A类是构造器注入B的结构:
public class A { private final B b; public A(B b) { this.b = b; } public String getAName(String id) { return "A_" + b.getBName(id); } }
对应的测试代码应该这么写:
import org.junit.jupiter.api.Test; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.junit.jupiter.api.extension.ExtendWith; import static org.mockito.Mockito.when; import static org.junit.jupiter.api.Assertions.assertEquals; @ExtendWith(MockitoExtension.class) public class ATest { // 先Mock出B对象 @Mock private B mockB; @Test void testGetAName() { // 1. 创建A实例时,传入Mock的B对象 A a = new A(mockB); // 2. 设置Mock行为:当调用mockB.getBName("testId")时,返回指定值 when(mockB.getBName("testId")).thenReturn("MockedB"); // 3. 调用A的目标方法 String result = a.getAName("testId"); // 4. 验证结果 assertEquals("A_MockedB", result); // 此时不会执行真实的b.getBName,因为用的是Mock的B实例 } }
场景2:A类通过Setter/字段注入B对象
如果A类是用Setter或者Spring的@Autowired字段注入B:
public class A { @Autowired private B b; public String getAName(String id) { return "A_" + b.getBName(id); } }
测试时可以用@InjectMocks自动注入Mock的B对象:
@ExtendWith(MockitoExtension.class) public class ATest { @Mock private B mockB; @InjectMocks // 自动把Mock的B注入到A实例中 private A a; @Test void testGetAName() { when(mockB.getBName("testId")).thenReturn("MockedB"); String result = a.getAName("testId"); assertEquals("A_MockedB", result); } }
你之前代码可能出问题的原因
- 没有使用Mock的B对象:如果A实例依赖的是真实的B对象,那必然会执行真实的
getBName方法,一定要确保A关联的是你Mock出来的B实例。 - Mock行为参数不匹配:比如你设置的是
when(mockB.getBName("wrongId")),但调用时传的是"testId",这时候Mock不会生效,若B是真实对象就会走真实逻辑。 - 误用
@Spy注解:如果给B用了@Spy而非@Mock,默认会执行真实方法,需要用doReturn(...).when(spyB).getBName(...)来强制覆盖。
特殊情况:B的方法是静态方法
如果b.getBName是静态方法,需要用MockedStatic来Mock:
@Test void testGetANameWithStaticB() { try (MockedStatic<B> mockedStaticB = Mockito.mockStatic(B.class)) { mockedStaticB.when(() -> B.getBName("testId")).thenReturn("MockedStaticB"); A a = new A(); String result = a.getAName("testId"); assertEquals("A_MockedStaticB", result); } }
内容的提问来源于stack exchange,提问作者Mahyar
相关产品推荐
相关产品推荐

