Flutter 颤振:小部件测试中的readAsBytes/readAsString
我正在尝试使用以下Flutter 颤振:小部件测试中的readAsBytes/readAsString,flutter,dart,widget-test-flutter,Flutter,Dart,Widget Test Flutter,我正在尝试使用以下onPressed函数测试StatefulWidget floatingActionButton:floatingActionButton( 子:图标(Icons.camera\u alt), onPressed:()异步{ 试一试{ 最终文件名=widget.randomStringGenerator?.call()??“”; 最终路径=连接( (等待getTemporaryDirectory())。路径, “${filename}.png”, ); wait widget.
onPressed
函数测试StatefulWidget
floatingActionButton:floatingActionButton(
子:图标(Icons.camera\u alt),
onPressed:()异步{
试一试{
最终文件名=widget.randomStringGenerator?.call()??“”;
最终路径=连接(
(等待getTemporaryDirectory())。路径,
“${filename}.png”,
);
wait widget.cameraController?.takePicture(路径);
最终文件=文件(路径);
final image=wait file.readAsBytes();
小部件。已拍照(图像);
等待文件。删除();
}捕获(e){
印刷品(e);
}
},
),
以及以下小部件测试:
void main(){
目录;
组('PhotoWidget测试',(){
设置(()异步{
//创建一个临时目录。
directory=wait directory.systemTemp.createTemp();
//模拟path_提供程序插件的MethodChannel。
const MethodChannel('plugins.flatter.io/path\u provider')
.setMockMethodCallHandler(
(MethodCall MethodCall)异步{
if(methodCall.method==“getTemporaryDirectory”){
返回directory.path;
}
返回null;
},
);
});
拆卸(()异步{
等待目录?是否删除(
是的,
);
});
testWidgets('onPictureTaken被称为',(WidgetTester)异步{
//给定
UINT8列表回调映像;
var expectedImage=base64.decode(
“Ivborw0kgoaaaansuh”
“Eugaaaaaababababayaaaa”
“FFCSJAAADULEQVR42MNK+”
‘P+/HgAFhAJ/wlseKgAAAA’
'BJRU5ERKJGG==',
);
var randomStringGenerator=()=>“测试简单照片”;
//连接文件路径
最终文件=文件(连接)(
directory.path,
“${randomStringGenerator()}.png”,
));
//将图像写入预期路径
writeAsBytesSync(expectedImage);
var cameraController=MockCameraController();
当(cameraController.initialize())。然后回答(()=>Future.value());
当(cameraController.value)。然后返回(
摄像值(
i初始化:错误,
),
);
var photoPage=SimplePhotoPage(
cameraController:cameraController,
randomStringGenerator:randomStringGenerator,
onphototake:(image)=>callbackImage=image,
);
//什么时候
等待测试仪.pumpWidget(
材料聚丙烯(
主页:photoPage,
),
);
等待测试器。点击(按类型查找(浮动操作按钮));
等待测试仪。泵和沉降器();
//然后
expect(callbackImage,expectedImage);
});
});
}
但是,此测试失败,调试时测试将在退出
final image=wait file.readAsBytes();
没有任何错误,也没有任何迹象表明出了什么问题。有趣的是,当我切换到它们的同步对应项(readAsBytesSync()
,deleteSync()
)时,测试通过了
从读取dart io库的源代码来看,它似乎是在一个单独的隔离中运行的
readAsBytes
,并且似乎没有在测试隔离中完成readAsBytes()。我不想使用此方法的同步版本。你们知道如何做到这一点吗?我也遇到了这个问题,无法理解为什么文件读取从未执行(或者没有抛出异常)
最后,我使用的是替换“dart:io”来传递一个接口到小部件以访问文件系统。这样就创建了一个构造函数
import 'package:file/memory.dart';
import 'package:file/file.dart'
class FSWidget extends StatefulWidget{
FileSystem _fs;
FSWidget({FilesSystem? fileSystem}): _fs = fileSystem?? MemoryFileSystem();
@override
_PostScreenState createState() => _PostScreenState();
}
}
这允许您使用传入自己的文件系统进行测试
临时文件系统访问代码变为
...
final filename = widget.randomStringGenerator?.call() ?? '';
final tempDirectory = await widget._fs.systemTempDirectory.createTemp('tempDir');
final outputFile = tempDirectory.childFile('${filename}.png');
await widget.cameraController?.takePicture(outputFile.path);
widget.onPhotoTaken(outputFile);
await outputFile.delete();
...
现在,您可以将对测试文件系统的引用传递给小部件
testWidgets('onPictureTaken is called', (WidgetTester tester) async {
FileSystem testFS = MemoryFileSystem();
// Add stuff to the filesystem
...
await tester.pumpWidget(
MaterialApp(
home: FSWidget(filesystem: testFS),
),
...
// Expect stuff from the filesystem
你有什么收获吗?