You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用Mockito为Records编写自动化测试遇问题求助

Dart Mockito无法为返回Record类型的方法生成Mock代码问题

问题背景

在方法中使用Dart Record作为返回类型时,Mockito生成测试用例的Mock代码失败,提示找不到FileModel和Uint8List类型,涉及updateHomeImage和createImage两个方法。

报错信息

test/cases/providers/home_provider_test.mocks.dart:1541:16: Error: Type 'FileModel' not found.
  _i13.Future<(FileModel, Uint8List)> createImage({
               ^^^^^^^^^
test/cases/providers/home_provider_test.mocks.dart:1541:27: Error: Type 'Uint8List' not found.
  _i13.Future<(FileModel, Uint8List)> createImage({
                          ^^^^^^^^^

相关代码

updateHomeImage方法

Future<(FileModel, Uint8List)> updateHomeImage(
      {File? image, Uint8List? bytes, Uint8List? imageBytes}) async {
    try {
      return kIsWeb
          ? await createImage(imageBytes: imageBytes, category: 'home-picture')
          : await createImage(image: image, category: 'home-picture');
    } on Exception {
      rethrow;
    }
  }

createImage方法

Future<(FileModel, Uint8List)> createImage({
    File? image,
    Uint8List? imageBytes,
    String? category,
  }) async {
    logger.fine('createImage called');
    var uri = Uri.parse('$filesPath/');
    FormData? formData;
    Options? options;
    Uint8List? bytes = Uint8List(0);

    try {
      if (kIsWeb) {
        Map<String, dynamic> mapData = {
          'file': MultipartFile.fromBytes(
            imageBytes!,
            filename: 'image.png',
            contentType: MediaType.parse('image/png'),
          ),
          'category': category,
        };
        formData = FormData.fromMap(mapData);

        options = Options(
          headers: {
            ...headers,
            'File-Path': 'image.png',
          },
        );
      } else {
        String fileName = image!.path.split('/').last;
        Map<String, dynamic> mapData = {
          'file': await MultipartFile.fromFile(
            image.path,
            filename: fileName,
            contentType: MediaType.parse('image/${image.path.split('.').last}'),
          ),
          'category': category,
        };
        formData = FormData.fromMap(mapData);

        options = Options(
          headers: {
            ...headers,
            'File-Path': image.path,
          },
        );
      }

      var response = await interceptedDio.postUri(
        uri,
        data: formData,
        options: options,
      );

      switch (imageBytes == null) {
        case true:
          return (FileModel.fromFileModelJson(response.data), bytes);
        default:
          return (FileModel.fromFileModelJson(response.data), imageBytes!);
      }
    } on DioException catch (e, s) {
      switch (e.type) {
        case DioExceptionType.cancel:
          logger.warning('request canceled');
          throw RequestCanceledException('request canceled');
        default:
          logger.shout('unhandled exception', e);
          await Sentry.captureException(e, stackTrace: s);
          throw Exception(e.message);
      }
    }
  }

解决思路建议

  • 检查Mock文件的导入语句:Mockito生成的mock文件可能缺失FileModel所在库的导入,以及dart:typed_data(Uint8List的依赖库)的导入。可以手动添加这些导入到mock文件,但注意重新生成mock时会被覆盖,建议通过配置持久化解决。
  • 确保类型的可见性:确认FileModel是公共类型(类名前没有下划线),Mockito无法识别私有类型。
  • 升级依赖版本:旧版本的Mockito对Dart Record的支持可能不完善,升级mockito和build_runner到最新稳定版,再重新生成mock代码。
  • 配置build.yaml指定导入:在项目根目录的build.yaml中为Mockito添加额外的导入配置,示例如下:
    targets:
      $default:
        builders:
          mockito:
            options:
              imports:
                - 'package:your_project_name/models/file_model.dart'
                - 'dart:typed_data'
    
    配置后重新运行flutter pub run build_runner build生成mock文件。
  • 检查测试文件的导入:确保测试文件中已经正确导入了FileModel和相关依赖库,Mockito生成代码时会参考测试文件的导入信息。

内容的提问来源于stack exchange,提问作者kalibear

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 01:37:18