Flutter审批流程插件approved的使用

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

Flutter审批流程插件approved的使用

approved

如何使用package:approved

package:approved 是一个用于快速编写单元测试、小部件测试和集成测试的库。它通过将预期状态保存在文件中而不是硬编码在代码中来简化测试过程。

示例代码

import 'dart:convert';

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Approved Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Approved Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() => setState(() => _counter++);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text('你已经按了按钮多少次:'),
            Text(
              '$_counter',
              key: const ValueKey('Counter'),
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        child: const Icon(Icons.add),
      ),
    );
  }
}

class Person {
  late Map<String, dynamic> data;

  Person() {
    data = {
      'name': 'John Doe',
      'age': 30,
      'email': 'john.doe@example.com',
      'pronoun': 'they',
    };
  }

  String toJson() => const JsonEncoder.withIndent('  ').convert(data);
}

快速开始视频

简要说明

什么是审批测试?

审批测试通常包含预期状态的硬编码值。与之不同的是,审批测试的预期状态被保存在一个文件中,而不是代码中。因为这些文件是由审批测试库生成的,而不是开发人员手动编写,所以编写和维护测试会更快,让开发人员可以更多地关注功能代码,而不是测试代码。

如何使用package:approved

假设你想确认页面加载时所有的组件都正确显示。为此,你可以调用 tester.approvalTest 并给你的测试一个合适的名称:

testWidgets('首页', (WidgetTester tester) async {
  await tester.pumpWidget(const MyApp());
  await tester.pumpAndSettle();

  await tester.approvalTest('所有组件正确加载');
});

第一次运行测试时,package:approved 会在当前目录下创建一个扩展名为 .unapproved.txt 的文件,并以测试名称作为文件名:

'首页 所有组件正确加载.unapproved.txt'

由于该文件尚未被批准,测试会失败。要审查文件并进行批准,可以运行以下命令:

dart run approved:review

dart run approved:review 命令还提供了其他选项,包括列出文件、根据索引选择文件进行审查等。要查看其当前功能,可以运行:

dart run approved:review --help

为了在测试文件中包含项目自定义的小部件类型,并执行测试后的检查,可以在测试的 setUpAlltearDownAll 中添加对 Approved.setUpAll()Approved.tearDownAll() 的调用:

main() {
  setUpAll(() {
    Approved.setUpAll();
  });

  tearDownAll(() {
    Approved.tearDownAll();
  });
}

输入 dart run approved:review 可能会很繁琐。可以通过在 .zshrc.bashrc 文件中设置别名来减少输入:

alias review='dart run approved:review'

或者在PowerShell配置文件中设置函数:

function review {
  dart run approved:review
}

非组件审批测试

审批测试不仅限于组件状态,还可以用于单元测试、BLoC测试等。对于非组件状态的测试数据,可以简单地调用 approvalTest 并传递文本格式的数据:

test('我的初始化测试', () {
  final myObject = MyObject();

  approvalTest('myObject构建正确', myObject.toJson());
});

更多关于Flutter审批流程插件approved的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter审批流程插件approved的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中使用approved插件来实现审批流程的示例代码。approved插件(假设存在,因为具体插件可能因实际名称和可用性而异)通常用于处理审批流程的逻辑,比如提交审批请求、查看审批状态等。

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

dependencies:
  flutter:
    sdk: flutter
  approved: ^latest_version  # 替换为实际最新版本号

然后运行flutter pub get来安装依赖。

接下来,你可以在你的Flutter应用中实现审批流程。以下是一个简单的示例,展示如何使用approved插件来提交审批请求并查看审批状态。

import 'package:flutter/material.dart';
import 'package:approved/approved.dart';  // 假设插件导入路径正确

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Approval Flow Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ApprovalFlowScreen(),
    );
  }
}

class ApprovalFlowScreen extends StatefulWidget {
  @override
  _ApprovalFlowScreenState createState() => _ApprovalFlowScreenState();
}

class _ApprovalFlowScreenState extends State<ApprovalFlowScreen> {
  final ApprovedController _approvedController = ApprovedController();
  ApprovalRequest? _currentRequest;

  @override
  void initState() {
    super.initState();
    // 初始化插件或设置监听器等
    _approvedController.init();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Approval Flow Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () async {
                // 创建并提交审批请求
                _currentRequest = ApprovalRequest(
                  title: 'Purchase Request',
                  description: 'Request to purchase new laptops',
                  applicant: 'John Doe',
                );
                
                try {
                  var response = await _approvedController.submitRequest(_currentRequest!);
                  print('Request submitted with ID: ${response.requestId}');
                } catch (e) {
                  print('Error submitting request: $e');
                }
              },
              child: Text('Submit Request'),
            ),
            SizedBox(height: 20),
            if (_currentRequest != null)
              FutureBuilder<ApprovalStatus>(
                future: _approvedController.checkStatus(_currentRequest!.requestId),
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return CircularProgressIndicator();
                  } else if (snapshot.hasError) {
                    return Text('Error checking status: ${snapshot.error}');
                  } else if (snapshot.hasData) {
                    var status = snapshot.data!;
                    return Text('Approval Status: ${status.status}');
                  } else {
                    return Text('No data');
                  }
                },
              ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    // 清理资源
    _approvedController.dispose();
    super.dispose();
  }
}

// 假设的审批请求数据模型
class ApprovalRequest {
  final String title;
  final String description;
  final String applicant;

  ApprovalRequest({required this.title, required this.description, required this.applicant});
}

// 假设的审批状态数据模型
class ApprovalStatus {
  final String status;

  ApprovalStatus({required this.status});
}

// 假设的 ApprovedController 类,用于与插件交互
class ApprovedController {
  Future<void> init() async {
    // 初始化代码,比如设置API密钥等
  }

  Future<SubmissionResponse> submitRequest(ApprovalRequest request) async {
    // 模拟提交请求的逻辑
    // 实际代码中,这里会调用插件提供的API
    await Future.delayed(Duration(seconds: 2)); // 模拟网络延迟
    return SubmissionResponse(requestId: 'req-12345');
  }

  Future<ApprovalStatus> checkStatus(String requestId) async {
    // 模拟检查审批状态的逻辑
    // 实际代码中,这里会调用插件提供的API
    await Future.delayed(Duration(seconds: 1)); // 模拟网络延迟
    return ApprovalStatus(status: 'Approved'); // 假设状态为已批准
  }

  void dispose() {
    // 清理资源
  }
}

// 假设的提交响应数据模型
class SubmissionResponse {
  final String requestId;

  SubmissionResponse({required this.requestId});
}

请注意,上述代码是一个简化的示例,用于展示如何使用假设的approved插件来实现审批流程的基本功能。在实际应用中,你需要根据插件的实际API和文档来调整代码。特别是ApprovedController类中的方法(如submitRequestcheckStatus)需要根据插件提供的实际API来实现。

回到顶部