使用Mockito模拟类局部变量:测试类A时参数匹配失败问题
解决Mockito参数匹配失败:Human实例不匹配的问题
这个问题我之前也碰到过,核心原因就是你在verify里新建的Human实例和类A内部持有的不是同一个对象——Mockito默认会用对象引用或者equals()方法来匹配参数,除非你的Human类重写了equals(),否则这两个不同的实例肯定匹配不上。下面给你几个可行的解决办法,你可以根据自己的测试场景选择:
1. 复用类A内部的Human实例
类A里的human是私有变量,我们可以通过反射把它取出来,然后用这个真实的实例去做verify匹配:
// 假设你已经创建了A的实例aInstance Field humanField = A.class.getDeclaredField("human"); humanField.setAccessible(true); // 打破私有访问限制 Human actualHuman = (Human) humanField.get(aInstance); // 用这个从A里拿到的实例做verify verify(service, times(1)).processFile(actualHuman);
2. 使用Mockito参数匹配器
如果不需要严格匹配具体实例,只要参数是Human类型就行,可以用any(Human.class):
verify(service, times(1)).processFile(any(Human.class));
要是你需要匹配Human对象的特定属性,可以用argThat()自定义匹配逻辑,比如检查某个属性值:
verify(service, times(1)).processFile(argThat(human -> human.getAge() == 25 && "Anna".equals(human.getName()) // 替换成你的实际匹配条件 ));
3. 给Human类重写equals()和hashCode()
如果希望两个Human对象只要属性相同就被视为相等,那直接重写这两个方法就行,这样Mockito用equals()比较时就会匹配成功:
public class Human { // 你的类属性,比如name、age等 private String name; private int age; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Human human = (Human) o; return age == human.age && Objects.equals(name, human.name); } @Override public int hashCode() { return Objects.hash(name, age); } }
4. 重构类A,改用依赖注入
最优雅的方式其实是重构类A,把Human对象改成依赖注入的形式,而不是在类内部直接new。这样测试时你可以自己创建Human实例并注入进去,verify时用同一个实例就行:
先修改类A:
public class A { private Human human; private SuperService service; // 构造方法注入依赖 public A(Human human, SuperService service) { this.human = human; this.service = service; } public void methodOne() { service.processFile(human); } }
然后测试代码:
// 测试时自己创建Human实例 Human testHuman = new Human(); // mock SuperService SuperService mockService = mock(SuperService.class); // 注入依赖创建A的实例 A aInstance = new A(testHuman, mockService); // 调用方法 aInstance.methodOne(); // 用同一个testHuman做verify verify(mockService, times(1)).processFile(testHuman);
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

