平台通道测试接口迁移到 flutter_test 包
概述
#以下方法已被 flutter_test 包中的 API 取代
BinaryMessenger.checkMessageHandlerBinaryMessenger.setMockMessageHandlerBinaryMessenger.checkMockMessageHandlerBasicMessageChannel.setMockMessageHandlerMethodChannel.checkMethodCallHandlerMethodChannel.setMockMethodCallHandlerMethodChannel.checkMockMethodCallHandler
Flutter 框架已不再使用 onPlatformMessage 回调。
背景
#作为底层插件通信架构重构的一部分,我们已从先前的 onPlatformMessage/handlePlatformMessage 逻辑迁移到引擎中实现的、在 ChannelBuffers 类中实现的每个通道的缓冲系统。为保持与现有代码的兼容性,现有的 BinaryMessenger.setMessageHandler API 已重构为使用新的 ChannelBuffers API。
ChannelBuffers API 与先前 API 之间的一个区别是,新 API 在异步处理方面更加一致。作为副作用,消息传递周围的 API 现在完全是异步的。
这给旧测试 API 的实现带来了问题,出于历史原因,这些 API 以前位于 flutter 包中。由于它们依赖于底层逻辑的部分同步,因此需要进行重构。为避免将更多测试逻辑添加到 flutter 包中,我们决定将此逻辑迁移到 flutter_test 包。
变更说明
#具体来说,以下 API 受到了影响
BinaryMessenger.checkMessageHandler:已废弃。BinaryMessenger.setMockMessageHandler:已由TestDefaultBinaryMessenger.setMockMessageHandler取代。BinaryMessenger.checkMockMessageHandler:已由TestDefaultBinaryMessenger.checkMockMessageHandler取代。BasicMessageChannel.setMockMessageHandler:已由TestDefaultBinaryMessenger.setMockDecodedMessageHandler取代。MethodChannel.checkMethodCallHandler:已废弃。MethodChannel.setMockMethodCallHandler:已由TestDefaultBinaryMessenger.setMockMethodCallHandler取代。MethodChannel.checkMockMethodCallHandler:已由TestDefaultBinaryMessenger.checkMockMessageHandler取代。
这些替换项仅适用于使用新的 TestDefaultBinaryMessengerBinding 的代码(例如,在 flutter_test 测试中使用 testWidgets 的任何代码)。对于之前使用这些 API 的生产代码没有替代方案,因为它们并非 intended for production code use。
使用 checkMessageHandler 的测试在新 API 中没有等效项,因为消息处理程序的注册直接由 ChannelBuffers 对象处理,该对象不公开通道当前注册的监听器。(验证处理程序注册的测试似乎很少见。)
需要迁移的代码可能会看到以下错误
error - The method 'setMockMessageHandler' isn't defined for the type 'BinaryMessenger' at test/sensors_test.dart:64:8 - (undefined_method)
error • The method 'setMockMethodCallHandler' isn't defined for the type 'MethodChannel' • test/widgets/editable_text_test.dart:5623:30 • undefined_method
[error] The method 'setMockMessageHandler' isn't defined for the type 'BasicMessageChannel' (test/material/feedback_test.dart:37:36)此外,以前由框架钩住以接收插件消息的 onPlatformMessage 回调已不再使用(并将适时移除)。因此,调用此回调以将消息注入框架不再有效。
迁移指南
#flutter_test 包提供了一些兼容层,以便使用已废弃的 setMock... 和 checkMock... 方法的代码能够继续工作。先前未导入 package:flutter_test/flutter_test.dart 的测试可以通过导入该包来启用这些兼容层;这应该足以迁移大多数代码。
然而,这些兼容层 API 已被弃用。相反,在使用 WidgetTester 的代码中(例如,使用 testWidgets),建议使用以下模式来替换对这些方法的调用(其中 tester 是 WidgetTester 实例)
// old code
ServicesBinding.defaultBinaryMessenger.setMockMessageHandler(...);
ServicesBinding.defaultBinaryMessenger.checkMockMessageHandler(...);
// new code
tester.binding.defaultBinaryMessenger.setMockMessageHandler(...);
tester.binding.defaultBinaryMessenger.checkMockMessageHandler(...);// old code
myChannel.setMockMessageHandler(...);
myChannel.checkMockMessageHandler(...);
// new code
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler(myChannel, ...);
tester.binding.defaultBinaryMessenger.checkMockMessageHandler(myChannel, ...);// old code
myMethodChannel.setMockMethodCallHandler(...);
myMethodChannel.checkMockMethodCallHandler(...);
// new code
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(myMethodChannel, ...);
tester.binding.defaultBinaryMessenger.checkMockMessageHandler(myMethodChannel, ...);使用 package:test 和 test() 的测试可以更改为使用 package:flutter_test 和 testWidgets() 来访问 WidgetTester。
没有 WidgetTester 访问权限的代码可以引用 TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger 而不是 tester.binding.defaultBinaryMessenger。
不使用默认测试小部件绑定(由 testWidgets initialised 的 AutomatedTestWidgetsFlutterBinding)的测试可以通过将 TestDefaultBinaryMessengerBinding mixin 混入其绑定来获得相同的结果。
操作 onPlatformMessage 的测试将不再按预期工作。要将模拟消息发送到框架,请考虑使用 ChannelBuffers.push。新 API 中没有用于拦截来自插件的消息并将其转发到框架的机制。如果您的用例需要此类机制,请提交 bug。
时间线
#已登陆版本:2.3.0-17.0.pre.1
稳定版本:2.5
参考资料
#API 文档
相关 PR