Flutter测试中如何正确mock path_provider以支持文件写入?
问题根因
你遇到的报错本质是mock返回的路径对应的父目录在测试运行环境中不存在:
path_provider的原生getApplicationSupportPath实现会自动创建对应目录,但你自定义的Fake类只返回了路径字符串,没有提前生成对应目录- Dart IO的文件写入逻辑不会自动创建父级目录,写入文件前如果父目录不存在就会抛出OS错误码2的
FileSystemException
正确Mock实现步骤
1. 定义符合测试场景的Fake类
不要硬编码不存在的固定路径,优先使用系统临时目录作为测试存储路径,避免权限问题:
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; import 'dart:io'; class FakePathProviderPlatform extends PathProviderPlatform { final Directory testTempDir; FakePathProviderPlatform(this.testTempDir); @override Future<String?> getApplicationSupportPath() async { // 返回临时目录下的模拟ApplicationSupport路径 final supportDir = Directory('${testTempDir.path}/app_support'); // 提前创建目录,避免后续写入报错 await supportDir.create(recursive: true); return supportDir.path; } // 如果你的代码用到path_provider的其他API,按需补充对应重写逻辑 }
2. 测试生命周期配置
在setUp中完成实例替换和临时目录初始化,tearDown中清理测试产生的临时文件:
import 'package:flutter_test/flutter_test.dart'; void main() { late Directory tempTestDir; setUp(() async { // 初始化系统临时目录 tempTestDir = await Directory.systemTemp.createTemp('image_test_'); // 替换path_provider的平台实例 PathProviderPlatform.instance = FakePathProviderPlatform(tempTestDir); }); tearDown(() async { // 测试结束后删除临时目录,避免残留文件 await tempTestDir.delete(recursive: true); }); // 你的测试用例 test('resizeImage should output correct size', () async { // 传入3000x4000的测试图片调用resizeImage // 后续尺寸校验逻辑正常执行即可 }); }
3. 补充业务代码健壮性(可选)
建议在resizeImage方法写入文件前增加父目录判断,避免线上环境也出现同类问题:
final outputFile = File('$outputPath/resizedImage.png'); // 写入前先确保父目录存在 await outputFile.parent.create(recursive: true); // 再执行图片写入逻辑 await outputFile.writeAsBytes(processedImageBytes);
内容的提问来源于stack exchange,提问作者Joel Broström
相关产品推荐
相关产品推荐

