Flutter中如何对文件保存读取功能进行单元测试
解决步骤
1. 先补充测试依赖
修改pubspec.yaml的dev_dependencies节点,新增路径提供工具的平台模拟依赖,用来解决单元测试环境下无法获取系统应用目录的问题:
dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^1.0.0 # 新增以下两个依赖 path_provider_platform_interface: ^2.0.1 plugin_platform_interface: ^2.0.2
2. 正确的单元测试实现
替换counter_test.dart的全部内容为以下代码,已经覆盖你提出的两个测试场景:
import 'package:flutter_test/flutter_test.dart'; import 'package:path_provider/path_provider.dart'; import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'package:write_file_test/main.dart'; import 'dart:io'; // 模拟系统路径提供能力 class MockPathProvider extends Mock with PathProviderPlatform { final String testDir; MockPathProvider(this.testDir); @override Future<String?> getApplicationDocumentsPath() async { return testDir; } } void main() { late Directory tempDir; // 测试前置:创建临时目录模拟应用的私有存储目录 setUpAll(() async { tempDir = await Directory.systemTemp.createTemp('counter_test'); PathProviderPlatform.instance = MockPathProvider(tempDir.path); }); // 测试后置:清理临时文件 tearDownAll(() async { await tempDir.delete(recursive: true); }); test('写入计数器功能正常', () async { final storage = CounterStorage(); const testCounter = 6; // 等待异步写入完成,拿到返回的文件对象 final writeResult = await storage.writeCounter(testCounter); // 可断言的内容1:返回的文件真实存在 expect(await writeResult.exists(), isTrue); // 可断言的内容2:读取到的数值和写入的数值一致 expect(await storage.readCounter(), testCounter); }); test('模拟应用重启后存储数据不丢失', () async { // 用第一个实例写入测试值,模拟应用运行时的存储操作 final beforeRestartStorage = CounterStorage(); const testCounter = 12; await beforeRestartStorage.writeCounter(testCounter); // 重新实例化存储类,模拟应用重启后重新初始化存储模块的场景 final afterRestartStorage = CounterStorage(); // 断言:新实例读取到的值和之前写入的值一致,说明数据持久化正常 expect(await afterRestartStorage.readCounter(), testCounter); }); }
问题对应说明
- 关于
writeCounter的返回值:它的返回类型是Future<File>,await后可以拿到写入完成的文件对象,可直接断言文件是否存在、文件内容是否符合预期,也可以通过配套的readCounter方法校验写入结果,后者更贴合业务逻辑的测试需求。 - 关于模拟应用重启:只需要写入完成后重新创建
CounterStorage实例即可,新实例对应应用重启后重新初始化的存储模块,底层文件是持久化保存在磁盘上的,不会因为类实例销毁而消失,只要新实例能读取到之前写入的值,就说明重启后数据不会丢失。
原测试代码的错误点
- 只声明了
CounterStorage变量没有初始化,调用方法会直接抛空异常 - 没有await异步的
writeCounter方法,直接拿到的是未完成的Future对象,无法校验结果 - 误用了Widget测试的
find相关API,单元测试仅测业务逻辑,不需要渲染界面,不需要这类API
内容的提问来源于stack exchange,提问作者AndrewCSP
相关产品推荐
相关产品推荐

