Flutter测试辅助插件riverpod_testing_library的使用

发布于 1周前 作者 nodeper 来自 Flutter

Flutter测试辅助插件riverpod_testing_library的使用

riverpod_testing_library 是一个用于简化 Riverpod 提供者(providers)测试的库。它专为与 Riverpod 状态管理包一起使用而设计,并受到 bloc_test 的启发。

快速开始

添加依赖

在您的 pubspec.yaml 文件中添加 riverpod_testing_library 作为开发依赖:

dev_dependencies:
  riverpod_testing_library: ^0.2.0

安装依赖:

dart pub get

支持的提供者类型

该库支持以下类型的 Riverpod 提供者:

  • Provider
  • (Async)NotifierProvider
  • StateNotifierProvider
  • FutureProvider
  • StreamProvider
  • StateProvider
  • ChangeNotifierProvider

API

以下是 providerTest 函数的主要参数及其描述:

参数 类型 默认值 描述
provider ProviderListenable<State> - 要测试的提供者
overrides List<Override> <Override>[] 重写特定提供者的行为
setUp FutureOr<void> Function()? - 设置任何依赖项
skip int 0 跳过某些状态
fireImmediately bool false 立即调用监听器
act FutureOr<void> Function(ProviderContainer container)? - 与提供者交互
expect Object Function()? - 断言提供者更新到预期状态
verify FutureOr<void> Function(ProviderContainer container)? - 额外验证/断言
tearDown FutureOr<void> Function()? - 测试运行后执行

使用示例

使用 providerTest 编写单元测试

providerTest 创建一个新的提供者特定测试案例,处理断言提供者按预期顺序更新状态。

示例代码

import 'package:riverpod_testing_library/riverpod_testing_library.dart';
import 'package:test/test.dart';

// 假设 counterProvider 和 Counter 已经定义
void main() {
  group('counterProvider', () {
    providerTest<int>(
      'emits the initial state when fireImmediately is true',
      provider: counterProvider,
      fireImmediately: true,
      expect: () => [0],
    );

    providerTest<int>(
      'emits [] when nothing is done',
      provider: counterProvider,
      expect: () => [],
    );

    providerTest<int>(
      'emits [1] when Counter.increment() is called',
      provider: counterProvider,
      act: (container) => container.read(counterProvider.notifier).increment(),
      expect: () => [1],
    );
  });
}

如果使用没有覆盖 ==hashCode 的状态类,可以提供匹配器而不是显式状态实例:

providerTest<int>(
  'emits [1] when Counter.increment() is called',
  provider: counterProvider,
  act: (container) => container.read(counterProvider.notifier).increment(),
  expect: () => [
    predicate<int>((value) {
      expect(value, 1);
      return true;
    }),
  ],
);

通过这些示例和 API 描述,您可以轻松地编写和维护基于 Riverpod 的应用的测试。


更多关于Flutter测试辅助插件riverpod_testing_library的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter测试辅助插件riverpod_testing_library的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于在Flutter中使用riverpod_testing_library进行测试,这里提供一个具体的代码案例来展示其基本用法。riverpod_testing_library是一个用于测试Riverpod状态管理的辅助库,它允许你更容易地创建和操控Provider的状态,以便在测试中验证UI行为。

首先,确保你的pubspec.yaml文件中已经添加了riverpodriverpod_testing_library的依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_riverpod: ^x.y.z  # 请替换为最新版本号

dev_dependencies:
  flutter_test:
    sdk: flutter
  riverpod_testing_library: ^x.y.z  # 请替换为最新版本号

接下来,我们创建一个简单的Riverpod应用,并使用riverpod_testing_library进行测试。

示例应用

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final counterProvider = StateProvider<int>((ref) => 0);

class CounterApp extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(counterProvider);
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Counter')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('You have pushed the button this many times:'),
              Text(
                '$count',
                style: Theme.of(context).textTheme.headline4,
              ),
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () => ref.read(counterProvider.notifier).increment(),
          tooltip: 'Increment',
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

测试代码

import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_testing_library/riverpod_testing_library.dart';
import 'package:your_app_package/main.dart';  // 请替换为你的主应用文件路径

void main() {
  testWidgets('Counter increments smoke test', (WidgetTester tester) async {
    // 创建一个测试环境
    final testEnvironment = TestEnvironment(
      initialState: {
        counterProvider: 0,  // 设置初始状态
      },
    );

    // 使用TestEnvironmentBuilder包装被测Widget
    await testEnvironment.pumpWidgetBuilder(
      tester,
      ProviderScope(
        child: CounterApp(),
      ),
    );

    // 验证初始状态
    expect(find.text('0'), findsOneWidget);

    // 模拟点击FloatingActionButton
    await tester.tap(find.byIcon(Icons.add));
    await tester.pump();  // 触发状态更新

    // 验证状态更新
    expect(find.text('1'), findsOneWidget);

    // 进一步测试,例如多次点击
    await tester.tap(find.byIcon(Icons.add));
    await tester.pump();
    expect(find.text('2'), findsOneWidget);

    // 你可以继续添加更多的测试逻辑
  });
}

解释

  1. 创建测试环境:使用TestEnvironment创建一个测试环境,并设置counterProvider的初始状态为0。
  2. 包装被测Widget:使用TestEnvironmentBuilderCounterApp包装在ProviderScope中,这样Riverpod的Provider就可以在测试环境中正常工作。
  3. 初始状态验证:使用WidgetTester查找并验证初始显示的文本为’0’。
  4. 模拟用户交互:模拟点击FloatingActionButton,并触发状态更新。
  5. 状态更新验证:验证点击后的文本更新为’1’和’2’。

这个示例展示了如何使用riverpod_testing_library来设置Provider的初始状态,并模拟用户交互来测试UI行为。希望这能帮助你更好地理解如何在Flutter项目中使用该库进行测试。

回到顶部