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

Flutter中如何Mock运行时创建的对象?

解决Flutter Widget测试中Mock数据库方法的问题

你现在的代码里saveData方法直接在内部实例化MyDatabase,这种硬编码的依赖关系导致没法用Mock替换真实的数据库实例。要解决这个问题,得先调整代码的依赖注入方式,再用mockito来Mock目标方法,具体步骤如下:

1. 重构代码,支持依赖注入

把MyDatabase的实例从saveData内部创建改为外部注入,最简单的方式是通过Widget的构造函数传入,不影响正常业务逻辑的同时,方便测试替换:

// 你的Widget类
class MyWidget extends StatefulWidget {
  // 新增数据库依赖参数,默认使用真实实例
  final MyDatabase db;

  const MyWidget({super.key, MyDatabase? db}) : db = db ?? MyDatabase();

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  void saveData(int number) async {
    // 不再自行创建db实例,使用Widget传入的对象
    bool success = await widget.db.insert(number);
    // ...后续业务逻辑
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () => saveData(123),
      child: const Text("Save Data"),
    );
  }
}

2. 用mockito生成Mock数据库类

首先在pubspec.yaml的开发依赖中添加mockito和build_runner:

dev_dependencies:
  flutter_test:
    sdk: flutter
  mockito: ^5.4.0
  build_runner: ^2.4.4

创建一个mock类文件(比如mock_database.dart):

import 'package:mockito/mockito.dart';
import 'your_database_file_path.dart'; // 导入真实的MyDatabase类

class MockMyDatabase extends Mock implements MyDatabase {}

运行命令生成Mock相关代码:

flutter pub run build_runner build

3. 编写测试代码

在测试中创建Mock实例,设置预期行为,注入到Widget后验证方法调用:

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'your_widget_file_path.dart';
import 'mock_database.dart';

void main() {
  testWidgets('测试按钮点击时调用Mock的insert方法', (tester) async {
    // 创建Mock数据库实例
    final mockDb = MockMyDatabase();
    
    // 设置预期:调用insert(123)时返回true
    when(mockDb.insert(123)).thenAnswer((_) async => true);
    
    // 将Mock实例注入Widget
    await tester.pumpWidget(MyWidget(db: mockDb));
    
    // 模拟按钮点击
    await tester.tap(find.text("Save Data"));
    await tester.pumpAndSettle(); // 等待异步操作完成
    
    // 验证insert方法是否按预期被调用
    verify(mockDb.insert(123)).called(1);
  });
}

补充说明

如果不想修改Widget构造函数,也可以用Provider、GetIt这类依赖注入框架管理MyDatabase实例,测试时替换成Mock对象即可——核心逻辑都是让依赖可以被外部替换,而非在方法内部硬创建。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 09:32:40