简体   繁体   English

如何在测试期间强制执行内存文件 io?

[英]How I can enforce in-memory file io during testing?

I am making a class for saving some user-provided settings to my application:我正在制作 class 以将一些用户提供的设置保存到我的应用程序中:

import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as p;

class UserSettings
{
   late final String _path;
   UserSettings(){
      String os = Platform.operatingSystem;
      String home = "";
      Map<String, String> envVars = Platform.environment;
      if (Platform.isMacOS || Platform.isLinux) {
        home = envVars['HOME'] as String;
      } else if (Platform.isWindows) {
        home = envVars['UserProfile'] as String;
      }

      _path = p.join(home, ".settings.json");
   }

   Future<Map<String, dynamic>> readSettings(File? settingFile) {
   
       if (settingFile == null) {
        settingsFile = File(_path);
      }

      if (!settingsFile.exists()) {
        return new Map<String, dynamic>();
      }

      String json = settingsFile.readAsString();
      Map<String, dynamic> settings = Map.castFrom(json.decode(json));

      return settings;
   }

   Future<Map<String, dynamic>> writeSettings(Strikg key, dynamic value) {
      File settingsFile = File(_path);
      Map<String,dynamic> settings = await readSettings();

      settings[key] = value;
      await settingsFile.writeAsString(json.encode(jsonData));
   }
}

And I want to test whether class is able to read and write the file correctly:我想测试 class 是否能够正确读写文件:


test('Test that accesstoken and Store is is written', () async {
    UserSettings settings = UserSettings();
    
    settings.writeSettings('mytoken','somevalue');
    settings.saveStoreId('myid',522);

    Map<String,dynamic> settings = settings.readSettings(null);

    assert(settings['store_id']==522,'Is is not saved');
    assert(settings['mytoken']=='somevalue','Token is not saved');
});

But as you can see I need to access the home folder.但正如您所见,我需要访问主文件夹。 Is there some way to mock the path with some in-memory one and emulate both cases that are windows or linux?有没有办法用一些内存中的路径来模拟路径并模拟 windows 或 linux 这两种情况?

Use package:file .使用package:file Any function that currently constructs File or Directory objects would need to be changed to take a FileSystem argument and instead would need to call methods on that ( FileSystem.file or FileSystem.directory ) to construct equivalent objects.当前构造FileDirectory对象的任何 function 都需要更改为采用FileSystem参数,而是需要调用该参数( FileSystem.fileFileSystem.directory )以构造等效对象。 Typically such FileSystem arguments can be optional and can default to const LocalFileSystem() .通常,此类FileSystem arguments 可以是可选的,并且可以默认为const LocalFileSystem() Note that functions that operate on File or Directory objects do not need to be changed since package:file provides File and Directory classes that have the same names and that implement the same interfaces as their dart:io counterparts.请注意,不需要更改对FileDirectory对象进行操作的函数,因为package:file提供了与dart:io对应的FileDirectory类具有相同的名称并实现相同的接口。

Tests then can create a MemoryFileSystem , set it up fake, in-memory files and directories, and pass that to your functions instead.然后测试可以创建一个MemoryFileSystem ,将其设置为虚假的内存文件和目录,然后将其传递给您的函数。

The typical way you'd enforce using package:file 's File and Directory classes instead of dart:io 's is to import dart:io only with a prefix: The typical way you'd enforce using package:file 's File and Directory classes instead of dart:io 's is to import dart:io only with a prefix:

import 'dart:io' as io;

to force its use to be explicit.强制其使用是明确的。 If adding io.如果添加io. prefixes throughout your code is too onerous, you alternatively can hide any conflicting classes.代码中的前缀太繁琐,您也可以隐藏任何冲突的类。 For example:例如:

import 'dart:io' hide File, Directory;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM