如何用Mockito测试类A的method1并验证B的execute方法执行?
解决方法
你的核心问题是类A中直接通过new B(org_id)创建B实例,Mockito无法直接拦截这种硬编码的对象创建,所以首先需要重构代码让B的依赖可注入,再进行交互验证。
步骤1:重构类A,让B的依赖可替换
有两种常见的重构方式:
方式1:通过构造器注入B的实例(推荐)
修改类A,允许通过构造器传入B的实例,这样测试时可以传入Mock的B:
class A { private final B b; // 生产环境使用这个构造器,传入真实的B实例 public A(String orgId) { this.b = new B(orgId); } // 测试专用构造器,直接传入B的实例 A(B b) { this.b = b; } void method1() { b.execute(); } }
方式2:抽取B的创建为可覆盖的方法
如果不方便修改构造器,可以把创建B的逻辑抽成一个protected方法,测试时用子类覆盖这个方法返回Mock对象:
class A { void method1() { B b = createB(org_id); // 调用抽取的方法 b.execute(); } // 抽取为protected方法,方便测试时覆盖 protected B createB(String orgId) { return new B(orgId); } }
步骤2:编写Mockito交互测试
针对方式1的测试代码
import org.junit.Test; import org.mockito.Mockito; public class ATest { @Test public void method1_shouldCallBExecute() { // 1. 创建Mock的B实例 B mockB = Mockito.mock(B.class); // 2. 创建A的实例,传入Mock的B A a = new A(mockB); // 3. 调用要测试的方法 a.method1(); // 4. 验证B的execute()方法被调用了一次 Mockito.verify(mockB, Mockito.times(1)).execute(); } }
针对方式2的测试代码
import org.junit.Test; import org.mockito.Mockito; public class ATest { @Test public void method1_shouldCallBExecute() { // 1. 创建A的Spy实例,用于覆盖createB方法 A spyA = Mockito.spy(new A()); B mockB = Mockito.mock(B.class); // 2. 指定当调用createB时返回Mock的B Mockito.doReturn(mockB).when(spyA).createB(Mockito.anyString()); // 3. 调用测试方法 spyA.method1(); // 4. 验证execute方法被调用一次 Mockito.verify(mockB, Mockito.times(1)).execute(); } }
额外说明:关于B中的静态方法
如果B的execute()方法里调用的静态方法(Dependency.m1()、Dependency.m2())导致测试报错,可以用Mockito的静态Mock功能(需Mockito 3.4+)来mock这些方法,示例:
import org.junit.Test; import org.mockito.MockedStatic; import org.mockito.Mockito; public class BTest { @Test public void execute_shouldCallDependencyMethods() { try (MockedStatic<B.Dependency> mockedStatic = Mockito.mockStatic(B.Dependency.class)) { // Mock静态方法的返回值 mockedStatic.when(B.Dependency::m1).thenReturn("mockValue1"); mockedStatic.when(B.Dependency::m2).thenReturn("mockValue2"); B b = new B("testOrg"); b.execute(); // 验证静态方法被调用 mockedStatic.verify(B.Dependency::m1, Mockito.times(1)); mockedStatic.verify(B.Dependency::m2, Mockito.times(1)); } } }
内容的提问来源于stack exchange,提问作者Poggy
相关产品推荐
相关产品推荐

