概述

#

以下方法已被 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),建议使用以下模式来替换对这些方法的调用(其中 testerWidgetTester 实例)

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:testtest() 的测试可以更改为使用 package:flutter_testtestWidgets() 来访问 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