跳至主要內容

將平台通道測試介面轉換至 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 完全是非同步的。

這為先前位於 flutter 套件中的舊版測試 API 的實作帶來了一個問題。由於它們依賴於底層邏輯部分是同步的,因此需要進行重構。為了避免在 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),建議使用以下模式來取代對這些方法的呼叫(其中 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 mixin 混入其綁定中以取得相同的結果。

操作 onPlatformMessage 的測試將不再按設計運作。若要將模擬訊息傳送至框架,請考慮使用 ChannelBuffers.push。在新 API 中,沒有機制可以攔截外掛程式的訊息並將其轉發到框架。如果您的使用案例需要此機制,請提交錯誤報告。

時程

#

已於版本中加入:2.3.0-17.0.pre.1
在穩定版本中:2.5

參考

#

API 文件

相關 PR