在Flutter测试中如何使用真实的PathProvider?

移动开发 2026-07-11

我有一个测试,如下所示:

void main() {

  TestWidgetsFlutterBinding.ensureInitialized();

  group('TabletFoldersTable widget', () {

    test("File Handler works", () async {
      Directory d = await getSessionDataRootFolder();
      expect(d.path, isNotEmpty);
    });
  }
}

// Method under test
static Future<Directory> getSessionDataRootFolder() async {
    if (Platform.isWindows) {
      Directory d = await getTemporaryDirectory();
      d = new Directory("${d.path}/$appSpecificDirectoryName");
      await d.create(recursive: true);
      return d;
    }
    return await getApplicationDocumentsDirectory();
}

不幸的是,这并不工作,因为我会收到一个异常,提示 MissingPluginException(No implementation found for method getTemporaryDirectory on channel plugins.flutter.io/path_provider)。在应用程序的正常运行中,一切正常。

我找到了关于如何模拟这些方法的各种页面,但它们似乎都相当复杂。

此外,在我正在处理的真实测试用例中,直接使用真实路径是完全可以的,因为这些路径有大量磁盘I/O,我不在意对它们进行模拟。

我观察到,在测试期间,PathProvider实例被设置为 MethodChannelPathProvider 以支持模拟,而在“真实”的情况下,它被设置为 PathProviderWindows(就我而言)。

那个类似乎并未公开可用,所以我不能仅用 PathProviderWindows.registerWith() 来初始化测试。

在测试中,如何使用与普通应用运行时相同的路径提供者?当然,理想情况下,这会自动选择当前平台的实现。

但如果我能让Windows版本工作,那就已经很好了。

解决方案

我找到了一个可能的变通办法:

当明确引用它们的包时,可以显式实例化特定于平台的变体。所以我做了

flutter pub add path_provider_windows
flutter pub add path_provider_foundation

然后我就可以直接引用这些实现,例如在测试开始时使用以下代码:

  if (Platform.isWindows) {
    PathProviderWindows.registerWith();
  }
  else if (Platform.isMacOS || Platform.isIOS) {
    PathProviderFoundation.registerWith();
  }
  else {
    throw new Exception("Please manually register a path provider for ${Platform.operatingSystem}");
  }

出于某种原因,我还需要把实现中的对 await File.stat()await Directory.create() 的某些调用替换为它们的同步等价物。否则测试会在异步调用处卡住。我还不知道原因。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章