You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用Mockito模拟SharedPreferences调用setString报MissingStubError错误

问题原因
  • Mockito在空安全模式下,默认要求所有非空返回值的方法必须提前配置桩(stub),哪怕你只需要验证方法调用、不需要关心返回值也需要配置
  • 你之前的getString测试用例已经提前用when给getString方法配置了桩,所以正常运行,但setString方法还没配置桩,所以调用时触发MissingStubError
  • setString方法的返回值是Future<bool>,属于非空类型,没有匹配桩的时候就会抛出异常
  • 你当前测试用例的执行顺序是先调用cacheLastNumberTrivia,此时就会触发setString执行,还没到verify步骤就会因为无桩抛出错误
解决方案

方案1:给setString方法提前配置桩(推荐)

在执行测试逻辑前,用when配置setString的返回值,不需要关心返回结果的话可以直接返回Future.value(true),修改测试用例如下:

test('should call sharedPreferences to cache the data', () {
  // 新增桩配置,any可匹配任意参数,也可替换为固定参数做精确匹配
  when(mockSharedPreferences.setString(any, any)).thenAnswer((_) async => true);
  // 执行测试逻辑
  dataSource.cacheLastNumberTrivia(tNumberTriviaModel);
  final expectedJsonString = jsonEncode(tNumberTriviaModel.toJson());
  // 验证调用
  verify(mockSharedPreferences.setString(cachedNumberTrivia, expectedJsonString));
});

如果配置桩后仍然报错,可检查传入的缓存key、序列化后的JSON字符串是否和实际调用的参数完全一致,优先用any匹配参数排查是否是参数匹配问题。

方案2:生成Mock类时开启returnNullOnMissingStub配置

如果不想每个方法都手动加桩,可以在生成Mock的注解中指定参数,修改模拟类生成配置:

@GenerateMocks([
  SharedPreferences
], customMocks: [
  MockSpec<SharedPreferences>(returnNullOnMissingStub: true)
])

修改后重新执行模拟类生成命令:
flutter pub run build_runner build
该方案所有未配置桩的方法都会默认返回null,无需逐个加桩,缺点是在需要非空返回的场景可能隐藏空安全问题,适合简单测试场景使用。

方案3:全局配置Mockito默认桩行为

如果需要配置全局生效,可以在测试文件的main方法最开头添加配置:

void main() {
  // 全局开启缺省桩返回null,关闭缺省抛错逻辑
  throwOnMissingStub = false;
  // 剩余测试代码
}

全局配置优先级低于单个Mock的returnNullOnMissingStub配置,也低于手动配置的when桩。

内容的提问来源于stack exchange,提问作者Naufal Rajabi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 17:36:03