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

Flutter单元测试报错:Binding尚未初始化(SharedPreference相关)

Flutter单元测试调用含SharedPreference的函数时出现“Binding has not yet been initialized”错误

问题场景

在Flutter单元测试中调用包含SharedPreferences的函数时触发Binding has not yet been initialized错误,禁用SharedPreferences相关代码后测试可正常运行。

错误原因

SharedPreferences的实现依赖Flutter的ServicesBinding,而普通的test()函数不会自动初始化这个绑定,导致调用SharedPreferences.getInstance()时触发绑定未初始化的错误。

解决方案

方案1:初始化测试绑定(快速解决)

在测试文件的main()函数开头添加TestWidgetsFlutterBinding.ensureInitialized(),手动初始化测试所需的绑定:

修改后的User_test.dart代码:

import 'package:flutter_test/flutter_test.dart';
import 'package:unit_testf/user.dart';

void main() {
  // 初始化测试绑定,解决SharedPreferences依赖的绑定问题
  TestWidgetsFlutterBinding.ensureInitialized();

  test("a unit test", () async {
    User user = User("flutter");
    final result = await user.userName();
    expect(result, true);
  });
}

方案2:使用Mock隔离外部依赖(推荐,符合单元测试原则)

单元测试应聚焦被测类的逻辑,而非依赖真实的存储实现。通过mockito包模拟SharedPreferences,彻底隔离外部依赖:

  1. 添加依赖
    在pubspec.yaml的dev_dependencies中添加:
dev_dependencies:
  flutter_test:
    sdk: flutter
  mockito: ^5.4.0
  build_runner: ^2.4.4
  1. 生成Mock类
    创建mock_shared_preferences.dart文件:
import 'package:mockito/mockito.dart';
import 'package:shared_preferences/shared_preferences.dart';

class MockSharedPreferences extends Mock implements SharedPreferences {}

运行命令生成mock代码:

flutter pub run build_runner build
  1. 修改被测类支持依赖注入
    调整User.dart,允许传入SharedPreferences实例,方便测试时注入mock:
import 'package:shared_preferences/shared_preferences.dart';

class User {
  final String name;
  final SharedPreferences? prefs;

  User(this.name, {this.prefs});

  Future<bool> userName() async {
    final prefsInstance = prefs ?? await SharedPreferences.getInstance();
    await prefsInstance.setString("name", name);
    return true;
  }
}
  1. 编写测试代码
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:unit_testf/user.dart';
import 'package:unit_testf/mock_shared_preferences.dart';

void main() {
  test("a unit test", () async {
    final mockPrefs = MockSharedPreferences();
    // 模拟setString方法返回true
    when(mockPrefs.setString("name", "flutter")).thenAnswer((_) async => true);

    User user = User("flutter", prefs: mockPrefs);
    final result = await user.userName();

    expect(result, true);
    // 验证setString是否按预期被调用
    verify(mockPrefs.setString("name", "flutter")).called(1);
  });
}

这种方式不仅解决了绑定问题,还能更精准地测试User类的逻辑,避免受平台环境影响,测试效率和稳定性更高。

内容的提问来源于stack exchange,提问作者Anand Suthar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 00:50:23