Flutter运行单元测试调用Google ML Kit出现MissingPluginException报错
问题原因
google_ml_kit属于依赖Android、iOS原生侧实现的平台插件,而Flutter默认的单元测试运行在纯Dart环境中,不会加载插件的原生实现,所以调用相关方法时会抛出MissingPluginException异常。
解决方案
方案1:Mock平台通道返回值(适用单元测试验证业务逻辑)
你可以在测试代码中手动模拟google_ml_kit对应通道的返回结果,修改后的测试代码示例如下:
import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:google_ml_kit/google_ml_kit.dart'; void main() { setUp(() { TestDefaultBinaryMessengerBinding.ensureInitialized(); const channel = MethodChannel('google_ml_kit'); // 为通道设置模拟方法回调 TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(channel, (call) async { switch (call.method) { case 'vision#startBarcodeScanner': return null; // 模拟扫描器启动成功 case 'vision#processImage': // 模拟返回空条码列表,匹配你当前测试的预期结果 return <Map<String, dynamic>>[]; // 如果需要模拟扫描到条码的场景,可以构造对应格式的返回数据,例如: // return [ // {'rawValue': 'test_code', 'format': 256} // 256对应二维码格式 // ]; case 'vision#closeBarcodeScanner': return null; // 模拟扫描器关闭成功 default: throw MissingPluginException('未实现的方法:${call.method}'); } }); }); tearDown(() { // 测试结束后清除模拟回调,避免影响其他测试用例 const channel = MethodChannel('google_ml_kit'); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(channel, null); }); test('barcode test',() async { BarcodeScannerUtil barcodeScannerUtil=BarcodeScannerUtil(); List<Barcode> barcodeList=await barcodeScannerUtil.getBarcode(InputImage.fromFilePath(r'C:\FlutterProjects\KK\Project\Dev\assets\images\ac.png')); expect(barcodeList.length, 0); }); }
注:如果是低于3.0版本的Flutter,可将TestDefaultBinaryMessengerBinding替换为ServicesBinding。
方案2:改用集成测试(适用验证真实扫码效果)
如果需要实际调用ML Kit的扫描能力验证真实功能效果,可将测试改为集成测试:
- 集成测试运行在真机或模拟器上,会加载完整的原生插件实现,可正常调用
processImage方法 - 测试代码需要放在项目根目录的
integration_test文件夹下,按照Flutter集成测试规范配置后运行即可。
方案3:抽象依赖后Mock工具类(适用上层业务逻辑测试)
如果你的测试目标是验证调用BarcodeScannerUtil的上层业务逻辑,可以先定义扫码工具的抽象接口,配合mockito这类Mock框架直接模拟getBarcode方法的返回值,不需要处理平台通道相关逻辑,测试的运行效率更高。
内容的提问来源于stack exchange,提问作者MSARKrish
相关产品推荐
相关产品推荐

