【问题标题】:Mock getExternalStorageDirectory on Flutter在 Flutter 上模拟 getExternalStorageDirectory
【发布时间】:2020-10-17 04:32:44
【问题描述】:

我正在尝试模拟函数 getExternalStorageDirectory,但总是返回错误: "UnsupportedError(不支持的操作:该功能仅在 Android 上可用)"

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

测试方法

    test('empty listReportModel', () async {
      
      TestWidgetsFlutterBinding.ensureInitialized();
      final directory = await Directory.systemTemp.createTemp();
      const MethodChannel channel =
          MethodChannel('plugins.flutter.io/path_provider');
      channel.setMockMethodCallHandler((MethodCall methodCall) async {
        if (methodCall.method == 'getExternalStorageDirectory') {
          return directory.path;
        }
        return ".";
      });

      when(Modular.get<IDailyGainsController>().listDailyGains())
          .thenAnswer((_) => Future.value(listDailyGainsModel));

      when(Modular.get<IReportsController>().listReports())
          .thenAnswer((_) => Future.value(new List<ReportsModel>()));

      var configurationController = Modular.get<IConfigurationController>();

      var response = await configurationController.createBackup();

      expect(response.filePath, null);
    });

方法

  Future<CreateBackupResponse> createBackup() async {
    CreateBackupResponse response = new CreateBackupResponse();

    var dailyGains = await exportDailyGainsToCSV();
    var reports = await exportReportsToCSV();

    final Directory directory = await getApplicationDocumentsDirectory();
    final Directory externalDirectory = await getExternalStorageDirectory();

    if (dailyGains.filePath != null && reports.filePath != null) {
      File dailyGainsFile = File(dailyGains.filePath);
      File reportsFile = File(reports.filePath);

      var encoder = ZipFileEncoder();
      encoder.create(externalDirectory.path + "/" + 'backup.zip');
      encoder.addFile(dailyGainsFile);
      encoder.addFile(reportsFile);
      encoder.close();

      await _removeFile(dailyGainsFile.path);
      await _removeFile(reportsFile.path);

      response.filePath = directory.path + "/" + 'backup.zip';
    }

    return response;
  }

【问题讨论】:

    标签: flutter dart mobile mocking


    【解决方案1】:

    pub.dev 所述:

    path_provider 现在使用PlatformInterface,这意味着不是所有 平台共享一个基于PlatformChannel 的实现。 随着这一变化,测试应该更新为模拟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;
      }
    }
    

    并通过以下方式构建您的测试:

    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);
        });
      } 
    }
    

    Here你可以查看完整的例子。

    【讨论】:

      猜你喜欢
      • 2021-11-01
      • 2019-06-20
      • 2021-06-30
      • 2018-10-24
      • 2021-08-31
      • 1970-01-01
      • 2022-09-28
      • 1970-01-01
      • 2023-04-09
      相关资源
      最近更新 更多