JUnit中如何用Mockito验证类成员的doSomething方法调用?
如何用Mockito验证MyObject内部Member的doSomething方法调用
你的问题核心在于MyObject构造时直接new Member()创建了内部实例,Mockito的spy无法拦截或替换这个已存在的真实对象,导致两种写法都失效:
- 第一种写法错误地验证了
getMember()方法的调用,而非doSomething() - 第二种写法验证的是真实的
Member实例,Mockito无法追踪其方法调用
下面是两种可行的解决方案:
方案1:重构MyObject,通过构造函数注入Member
这是最推荐的方式,符合依赖注入原则,也让测试更简单:
// 修改MyObject的构造函数,接收Member参数 public class MyObject { private final Member member; public MyObject(Member member) { this.member = member; } // 你的业务方法,比如调用member.doSomething() public void execute() { member.doSomething(new OneClass()); } }
测试代码:
@Test public void testMemberDoSomethingCalled() { // 创建Mock的Member实例 Member mockMember = Mockito.mock(Member.class); // 用Mock的Member创建MyObject MyObject myObject = new MyObject(mockMember); // 执行触发doSomething的业务方法 myObject.execute(); // 验证Mock的Member的doSomething方法被调用至少一次 Mockito.verify(mockMember, Mockito.atLeastOnce()).doSomething(Mockito.any(OneClass.class)); }
方案2:用Mockito的@InjectMocks替换内部Member(无需修改构造)
如果暂时不能修改MyObject的构造,可以通过Mockito的注解反射替换内部的member字段:
import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) // JUnit 5用MockitoExtension public class MyObjectTest { @Mock private Member mockMember; // 生成Mock的Member @InjectMocks private MyObject myObject; // Mockito自动将mockMember注入到myObject的member字段 @Test public void testDoSomethingInvocation() { // 执行触发member.doSomething()的业务逻辑 myObject.execute(); // 验证Mock的Member方法调用 verify(mockMember, atLeastOnce()).doSomething(any(OneClass.class)); } }
注意:这种方式要求MyObject的member字段可以被反射访问(比如private字段Mockito也能处理,但如果是final字段则不行)。
内容的提问来源于stack exchange,提问作者Olivier_22
相关产品推荐
相关产品推荐

