Mockito v5.x中使用verify(() => Mock对象.Getter)抛出'Used on a non-mockito object'错误的原因咨询
问题根源:Mockito对getter与方法的Lambda处理逻辑差异
这个问题其实是Mockito v5+版本中,getter调用和方法调用在lambda验证语法中的处理机制不同导致的,并非你的mock类生成错误或配置问题,我来逐一拆解:
1. 为什么verify(() => internetConnectionChecker.hasConnection)会报错?
当你使用verify(() => ...)的lambda语法时,对于方法调用(比如verify(() => mock.someMethod())),Mockito能正确识别这是在描述一个「方法调用行为」,不会实际执行方法,而是捕获调用意图用于验证。
但对于getter,逻辑完全不同:() => internetConnectionChecker.hasConnection这个lambda会被直接执行求值,返回的是hasConnection getter的结果(也就是一个Future<bool>对象)。Mockito拿到这个结果后,发现它不是mock对象,就会抛出你看到的「Used on a non-mockito object」错误——它误以为你要验证的是这个Future对象,而非getter的调用行为。
2. 为什么verify(internetConnectionChecker.hasConnection)能工作(但不推荐)?
这种写法是利用了Mockito的隐式跟踪机制:当你直接调用mock对象的getter时,Mockito会在内部记录这个调用行为,此时把getter的返回值传给verify,它能通过内部关联找到对应的调用记录。但这种写法确实不推荐,原因有二:
- 它依赖Mockito的内部实现细节,后续版本可能存在变更风险;
- 如果getter存在副作用(虽然最佳实践中getter不应该有),会导致意外的测试行为。
3. 官方推荐的正确解决方案:使用verifyGet
Mockito v5+专门为getter验证新增了verifyGet API,这是官方推荐的、安全的验证getter调用的方式。它能正确识别lambda中的getter调用行为,不会执行getter求值,而是精准捕获调用意图。
修改你的测试代码如下即可:
test('should check internet connection', () async { // Arrange when(() => internetConnectionChecker.hasConnection) .thenAnswer((_) async => true); // Act final result = await networkInfo.isConnect; // Assert verifyGet(() => internetConnectionChecker.hasConnection); // ✅ 官方推荐写法 expect(result, true); });
补充验证点
- 确认你的
mockito版本确实是v5.x+(verifyGet是v5版本引入的专属API); - 你已经通过
build_runner正确生成了mock类,这部分操作是完全正确的; - 这种处理方式是Mockito v5的设计变更,目的是更清晰地区分方法和getter的验证语义,避免lambda求值带来的歧义。
内容来源于stack exchange

