跳至主要内容

平台通道测试接口迁移到 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),建议使用以下模式来替换对这些方法的调用(其中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

不使用默认测试窗口小部件绑定(AutomatedTestWidgetsFlutterBinding,由testWidgets初始化)的测试可以将TestDefaultBinaryMessengerBinding混合到它们的绑定中以获得相同的结果。

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

时间线

#

包含版本:2.3.0-17.0.pre.1
稳定版发布:2.5

参考

#

API 文档

相关 PR