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

如何Mock Riverpod的Notifier并设置其状态?Mock使用方法咨询

Mock Riverpod Notifier 并设置状态的实操指南

1. 准备依赖

使用MockMixin需要先添加相关开发依赖,在pubspec.yaml的dev_dependencies节点下补充:

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

执行flutter pub get完成依赖安装。

2. 创建Mock Notifier类

基于你提供的示例,创建对应Mock类(需继承目标Notifier的基类,同时混入Mock并实现目标Notifier):

import 'package:riverpod/riverpod.dart';
import 'package:mockito/mockito.dart';

// 原Notifier类
class MyNotifier extends Notifier<int> {
  @override
  int build() => throw UnimplementedError();
  
  // 示例自定义方法:更新状态
  void updateState(int newState) => state = newState;
}

// Mock类
class MyNotifierMock extends Notifier<int> with Mock implements MyNotifier {}

执行flutter pub run build_runner build生成mock相关辅助代码,提升mock功能完整性。

3. 注入Mock到Provider

测试时需要通过ProviderScope的overrides替换原Provider的实现,注入Mock实例:

// 原Provider定义
final myNotifierProvider = NotifierProvider<MyNotifier, int>(() => MyNotifier());

// 测试中注入Mock
test('测试Mock Notifier', () async {
  final mockNotifier = MyNotifierMock();
  
  await ProviderScope(
    overrides: [
      myNotifierProvider.overrideWith(() => mockNotifier),
    ],
    child: // 这里可以嵌入测试用Widget或直接编写测试逻辑
  );
});

4. 设置Mock状态的几种方式

方式一:直接赋值状态

Mock类是Notifier的子类,可直接访问并修改state:

final mockNotifier = MyNotifierMock();
// 设置初始状态
mockNotifier.state = 10;
// 验证状态
expect(mockNotifier.state, 10);

方式二:模拟build方法的返回值

如果测试依赖build方法返回的初始状态,用mockito的when来模拟:

final mockNotifier = MyNotifierMock();
// 模拟build方法返回初始值
when(mockNotifier.build()).thenReturn(15);
// 触发build(Provider初始化时会自动调用)
mockNotifier.build();
expect(mockNotifier.state, 15);

方式三:模拟自定义方法并同步状态

如果Notifier有自定义方法,可模拟方法行为并同步修改状态:

final mockNotifier = MyNotifierMock();
mockNotifier.state = 5;

// 模拟updateState方法,调用时更新状态
when(mockNotifier.updateState(any)).thenAnswer((invocation) {
  final newState = invocation.positionalArguments[0] as int;
  mockNotifier.state = newState;
});

// 调用自定义方法
mockNotifier.updateState(20);
expect(mockNotifier.state, 20);
// 验证方法被调用过
verify(mockNotifier.updateState(20)).called(1);

5. 完整测试示例

import 'package:flutter_test/flutter_test.dart';
import 'package:riverpod/riverpod.dart';
import 'package:mockito/mockito.dart';

class MyNotifier extends Notifier<int> {
  @override
  int build() => 0; // 实际业务的初始状态
  
  void increment() => state++;
}

class MyNotifierMock extends Notifier<int> with Mock implements MyNotifier {}

final myNotifierProvider = NotifierProvider<MyNotifier, int>(() => MyNotifier());

void main() {
  test('验证Mock Notifier状态修改', () {
    final mockNotifier = MyNotifierMock();
    mockNotifier.state = 3;
    
    // 验证初始状态
    expect(mockNotifier.state, 3);
    
    // 模拟increment方法
    when(mockNotifier.increment()).thenAnswer((_) => mockNotifier.state++);
    
    mockNotifier.increment();
    expect(mockNotifier.state, 4);
    
    // 验证方法调用次数
    verify(mockNotifier.increment()).called(1);
  });
  
  test('在ProviderScope中使用Mock Notifier', () async {
    final mockNotifier = MyNotifierMock();
    mockNotifier.state = 7;
    
    await ProviderScope(
      overrides: [
        myNotifierProvider.overrideWith(() => mockNotifier),
      ],
      child: Builder(
        builder: (context) {
          final ref = ProviderScope.containerOf(context);
          final currentState = ref.watch(myNotifierProvider);
          expect(currentState, 7);
          return const SizedBox.shrink();
        },
      ),
    );
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 02:50:56