平台通道测试接口迁移到 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 的生产代码,没有替换方案,因为它们并非旨在用于生产代码。
使用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
。
不使用默认测试窗口小部件绑定(AutomatedTestWidgetsFlutterBinding
,由testWidgets
初始化)的测试可以将TestDefaultBinaryMessengerBinding
混合到它们的绑定中以获得相同的结果。
操作onPlatformMessage
的测试将不再按设计工作。要向框架发送模拟消息,请考虑使用ChannelBuffers.push
。在新 API 中,没有机制可以拦截来自插件的消息并将其转发到框架。如果您的用例需要此类机制,请提交错误报告。
时间线
#包含版本:2.3.0-17.0.pre.1
稳定版发布:2.5
参考
#API 文档
相关 PR
除非另有说明,否则本网站上的文档反映了 Flutter 的最新稳定版本。页面上次更新于 2024-04-04。 查看源代码 或 报告问题.