概述

#

以下方法已替换为 `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` 包提供了一些 shim,以便继续使用废弃的 `setMock...` 和 `checkMock...` 方法。以前未导入 `package:flutter_test/flutter_test.dart` 的测试可以导入它以启用这些 shim;这应该足以迁移大多数代码。

然而,这些 shim API 已被弃用。相反,在使用 `WidgetTester` 的代码中(例如,使用 `testWidgets`),建议使用以下模式来替换对这些方法的调用(其中 `tester` 是 `WidgetTester` 实例)

dart
// old code
ServicesBinding.defaultBinaryMessenger.setMockMessageHandler(...);
ServicesBinding.defaultBinaryMessenger.checkMockMessageHandler(...);
// new code
tester.binding.defaultBinaryMessenger.setMockMessageHandler(...);
tester.binding.defaultBinaryMessenger.checkMockMessageHandler(...);
dart
// old code
myChannel.setMockMessageHandler(...);
myChannel.checkMockMessageHandler(...);
// new code
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler(myChannel, ...);
tester.binding.defaultBinaryMessenger.checkMockMessageHandler(myChannel, ...);
dart
// 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`。

不使用默认测试 widget 绑定(`AutomatedTestWidgetsFlutterBinding`,由 `testWidgets` 初始化)的测试可以将 `TestDefaultBinaryMessengerBinding` mixin 混入其绑定中以获得相同的结果。

操纵 `onPlatformMessage` 的测试将不再按设计运行。要向框架发送模拟消息,请考虑使用 `ChannelBuffers.push`。在新 API 中,没有拦截来自插件的消息并将其转发到框架的机制。如果您的用例需要此类机制,请提交错误报告。

时间线

#

引入版本: 2.3.0-17.0.pre.1
稳定版本:2.5

参考资料

#

API 文档

相关 PR