平台通道测试接口迁移到 flutter_test 包
概述
#以下方法已被 flutter_test
包中的 API 取代
BinaryMessenger.checkMessageHandler
BinaryMessenger.setMockMessageHandler
BinaryMessenger.checkMockMessageHandler
BasicMessageChannel.setMockMessageHandler
MethodChannel.checkMethodCallHandler
MethodChannel.setMockMethodCallHandler
MethodChannel.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