Flutter 测试中的插件
将插件添加到你的 Flutter 测试中。
几乎所有的 Flutter 插件 都有两个部分
- Dart 代码,它提供你的代码调用的 API。
- 用特定平台(或“宿主”)语言编写的代码,例如 Kotlin 或 Swift,它实现了这些 API。
事实上,本机(或宿主)语言代码区分了插件包和标准包。
构建和注册插件的宿主部分是 Flutter 应用构建过程的一部分,因此插件只有在你的代码在你的应用中运行时才有效,例如使用 flutter run 或运行 集成测试。当运行 Dart 单元测试 或 widget 测试 时,本机代码不可用。如果你正在测试的代码调用了任何插件,这通常会导致以下错误
MissingPluginException(No implementation found for method someMethodName on channel some_channel_name)
在单元测试使用插件的代码时,有几种方法可以避免此异常。以下解决方案按优先顺序排列。
封装插件
#在大多数情况下,最好的方法是将插件调用封装在自己的 API 中,并提供一种在测试中 模拟 自己的 API 的方法。
这有几个优点
- 如果插件 API 发生更改,你无需更新你的测试。
- 你只测试自己的代码,因此你的测试不会因你使用的插件的行为而失败。
- 你可以使用相同的方法,无论插件是如何实现的,甚至对于非插件包依赖项。
模拟插件的公共 API
#如果插件的 API 已经基于类实例,你可以直接模拟它,但需要注意以下几点
- 如果插件使用非类函数或静态方法,这将不起作用。
- 当插件 API 更改时,需要更新测试。
模拟插件的平台接口
#如果插件是 联合插件,它将包含一个平台接口,允许注册其内部逻辑的实现。你可以注册该平台接口实现的模拟,而不是公共 API,但需要注意以下几点
- 如果插件不是联合插件,这将不起作用。
- 你的测试将包含插件的一部分代码,因此插件行为可能会给你的测试带来问题。例如,如果插件作为内部缓存的一部分写入文件,你的测试行为可能会根据你是否之前运行过测试而发生变化。
- 当平台接口发生更改时,可能需要更新测试。
一个需要这样做示例是模拟用于你依赖的包的插件的实现,而不是你自己的代码,以便你无法更改它的调用方式。但是,如果可能的话,你应该模拟使用插件的依赖项。
模拟平台通道
#如果插件使用 平台通道,你可以使用 TestDefaultBinaryMessenger 模拟平台通道。只有在出于某种原因,以上方法都不可用时,才应使用此方法,因为它有几个缺点
- 只有使用平台通道的实现才能被模拟。这意味着如果某些实现不使用平台通道,你的测试在某些平台上运行时将意外地使用真实实现。
- 平台通道通常是插件的内部实现细节。即使在插件的错误修复更新中,它们也可能发生重大变化,从而意外地破坏你的测试。
- 平台通道可能因联合插件的每个实现而异。例如,你可能设置了模拟平台通道以使测试在 Windows 机器上通过,然后发现它们在 macOS 或 Linux 上失败。
- 平台通道没有强类型。例如,方法通道通常使用字典,你必须阅读插件的实现才能知道键字符串和值类型是什么。
由于这些限制,TestDefaultBinaryMessenger 主要用于插件实现的内部测试,而不是使用插件的代码的测试。
你可能还想查看 测试插件。