Flutter 上的模拟 getExternalStorageDirectory

Gui*_*lho 7 mobile mocking dart flutter

我\xc2\xb4m尝试模拟函数getExternalStorageDirectory,但总是返回错误:\n“UnsupportedError(不支持的操作:功能仅在Android上可用)”

\n

我\xc2\xb4m使用setMockMethodCallHandler方法来模拟它,但错误发生在该方法被调用之前。

\n

测试方法

\n
    test('empty listReportModel', () async {\n      \n      TestWidgetsFlutterBinding.ensureInitialized();\n      final directory = await Directory.systemTemp.createTemp();\n      const MethodChannel channel =\n          MethodChannel('plugins.flutter.io/path_provider');\n      channel.setMockMethodCallHandler((MethodCall methodCall) async {\n        if (methodCall.method == 'getExternalStorageDirectory') {\n          return directory.path;\n        }\n        return ".";\n      });\n\n      when(Modular.get<IDailyGainsController>().listDailyGains())\n          .thenAnswer((_) => Future.value(listDailyGainsModel));\n\n      when(Modular.get<IReportsController>().listReports())\n          .thenAnswer((_) => Future.value(new List<ReportsModel>()));\n\n      var configurationController = Modular.get<IConfigurationController>();\n\n      var response = await configurationController.createBackup();\n\n      expect(response.filePath, null);\n    });\n
Run Code Online (Sandbox Code Playgroud)\n

方法

\n
  Future<CreateBackupResponse> createBackup() async {\n    CreateBackupResponse response = new CreateBackupResponse();\n\n    var dailyGains = await exportDailyGainsToCSV();\n    var reports = await exportReportsToCSV();\n\n    final Directory directory = await getApplicationDocumentsDirectory();\n    final Directory externalDirectory = await getExternalStorageDirectory();\n\n    if (dailyGains.filePath != null && reports.filePath != null) {\n      File dailyGainsFile = File(dailyGains.filePath);\n      File reportsFile = File(reports.filePath);\n\n      var encoder = ZipFileEncoder();\n      encoder.create(externalDirectory.path + "/" + 'backup.zip');\n      encoder.addFile(dailyGainsFile);\n      encoder.addFile(reportsFile);\n      encoder.close();\n\n      await _removeFile(dailyGainsFile.path);\n      await _removeFile(reportsFile.path);\n\n      response.filePath = directory.path + "/" + 'backup.zip';\n    }\n\n    return response;\n  }\n
Run Code Online (Sandbox Code Playgroud)\n

Ent*_*ain 12

正如pub.dev中所述:

path_provider现在使用 a PlatformInterface,这意味着并非所有平台都共享PlatformChannel基于 single 的实现。随着这一变化,测试应该更新为模拟PathProviderPlatform 而不是PlatformChannel.

这意味着您在测试目录中的某个位置创建了以下模拟类:

import 'package:mockito/mockito.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';

const String kTemporaryPath = 'temporaryPath';
const String kApplicationSupportPath = 'applicationSupportPath';
const String kDownloadsPath = 'downloadsPath';
const String kLibraryPath = 'libraryPath';
const String kApplicationDocumentsPath = 'applicationDocumentsPath';
const String kExternalCachePath = 'externalCachePath';
const String kExternalStoragePath = 'externalStoragePath';

class MockPathProviderPlatform extends Mock
    with MockPlatformInterfaceMixin
    implements PathProviderPlatform {
  Future<String> getTemporaryPath() async {
    return kTemporaryPath;
  }

  Future<String> getApplicationSupportPath() async {
    return kApplicationSupportPath;
  }

  Future<String> getLibraryPath() async {
    return kLibraryPath;
  }

  Future<String> getApplicationDocumentsPath() async {
    return kApplicationDocumentsPath;
  }

  Future<String> getExternalStoragePath() async {
    return kExternalStoragePath;
  }

  Future<List<String>> getExternalCachePaths() async {
    return <String>[kExternalCachePath];
  }

  Future<List<String>> getExternalStoragePaths({
    StorageDirectory type,
  }) async {
    return <String>[kExternalStoragePath];
  }

  Future<String> getDownloadsPath() async {
    return kDownloadsPath;
  }
}
Run Code Online (Sandbox Code Playgroud)

并按以下方式构建测试:

void main() {
  group('PathProvider', () {
    TestWidgetsFlutterBinding.ensureInitialized();

    setUp(() async {
      PathProviderPlatform.instance = MockPathProviderPlatform();
      // This is required because we manually register the Linux path provider when on the Linux platform.
      // Will be removed when automatic registration of dart plugins is implemented.
      // See this issue https://github.com/flutter/flutter/issues/52267 for details
      disablePathProviderPlatformOverride = true;
    });

    test('getTemporaryDirectory', () async {
      Directory result = await getTemporaryDirectory();
      expect(result.path, kTemporaryPath);
    });
  } 
}
Run Code Online (Sandbox Code Playgroud)

在这里您可以查看完整的示例。