Flutter 測試中的插件
在 Flutter 測試中加入插件。
幾乎所有 Flutter 插件 都包含兩個部分:
- Dart 程式碼,提供您的程式呼叫的 API。
- 以平台專屬(或稱「host」)語言(如 Kotlin 或 Swift)撰寫的程式碼,負責實作這些 API。
事實上,原生(host)語言的程式碼正是區分插件套件與標準套件的關鍵。
建置並註冊插件的 host 部分,是 Flutter 應用程式建置流程的一部分,
因此插件僅在您的程式碼於應用程式中執行時才會運作,例如使用 flutter run
或執行 整合測試 時。
當執行 Dart 單元測試 或
元件測試
時,host 程式碼並不可用。
如果您正在測試的程式碼有呼叫任何插件,
通常會導致如下錯誤:
MissingPluginException(No implementation found for method someMethodName on channel some_channel_name)
當你在單元測試中測試使用 plugin 的程式碼時, 有幾種方式可以避免這個例外。 以下解決方案依推薦順序排列。
將 plugin 呼叫包裝起來
#在大多數情況下,最佳做法是將 plugin 的呼叫包裝在你自己的 API 中, 並在測試時提供 mock 你自己 API 的方式。
這麼做有幾個優點:
- 如果 plugin 的 API 有變動, 你不需要更新測試。
- 你只會測試自己的程式碼, 測試不會因為你所使用的 plugin 行為而失敗。
- 不論 plugin 的實作方式為何, 甚至是非 plugin 的套件依賴, 你都可以用相同的方式進行測試。
Mock plugin 的公開 API
#如果 plugin 的 API 已經是基於類別實例, 你可以直接 mock 它,但需注意以下事項:
- 如果 plugin 使用的是非類別函式或靜態方法, 這種方式將無法運作。
- 當 plugin API 變動時, 測試也需要跟著更新。
Mock plugin 的平台介面
#如果 plugin 是 federated plugin, 它會包含一個平台介面(platform interface), 允許註冊其內部邏輯的實作。 你可以註冊該平台介面的 mock 實作, 而不是 mock 公開 API,但需注意以下事項:
- 如果 plugin 不是 federated plugin,這種方式將無法運作。
- 你的測試會包含部分 plugin 的程式碼, 因此 plugin 的行為可能會對你的測試造成影響。 例如,如果某個 plugin 會在內部快取時寫入檔案, 你的測試行為可能會因為是否曾經執行過而改變。
- 當平台介面變動時,測試可能也需要更新。
這種方式可能必要的情境是: 你依賴的某個套件使用了 plugin, 而不是你自己的程式碼, 因此你無法改變呼叫方式。 不過,如果可能的話, 你應該 mock 那個使用 plugin 的依賴,而不是直接 mock plugin。
Mock 平台通道(platform channel)
#
如果 plugin 使用 平台通道(platform channels),
你可以使用 TestDefaultBinaryMessenger
來 mock 這些平台通道。
只有在上述方法都不可行時,才建議使用這種方式,
因為它有以下幾個缺點:
- 只有使用平台通道實作的 plugin 才能被 mock。 這代表如果有些實作沒有用到平台通道, 你的測試在某些平台上會意外地使用到真實實作。
- 平台通道通常是 plugin 的內部實作細節。 即使是 plugin 的 bugfix 更新,也可能大幅更動, 造成測試意外失敗。
- 在 federated plugin 的每個實作中,平台通道可能不同。 例如,你可能設置了 mock 平台通道, 讓測試在 Windows 機器上通過, 但在 macOS 或 Linux 上執行時卻失敗。
- 平台通道並非強型別。 例如,method channel 通常使用字典(dictionary), 你必須閱讀 plugin 的實作才能知道 key 字串與 value 型別。
由於這些限制,TestDefaultBinaryMessenger
主要適用於 plugin 實作本身的內部測試,
而不是用於測試使用 plugin 的程式碼。
你也可以參考 Testing plugins。
Unless stated otherwise, the documentation on this site reflects Flutter 3.44.0. Page last updated on 2026-06-14. View source or report an issue.