概述

#

以下方法已被 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