Flutter手动时钟控制插件manual_clock的使用

Flutter手动时钟控制插件manual_clock的使用

该插件用于测试当前时间和定时器相关的代码。

ManualClock 类是一个继承自 Clock 的类。通过使用 clockfake_async 库,你可以通过 clock.now() 来测试当前时间相关的代码。但在 fake_async 回调内,你不能使用 await。由于这一限制,有时测试代码会变得困难。使用此库,你可以在测试当前时间和定时器相关代码时使用 await

限制

  • 持续时间为0的周期性定时器不被支持。
  • 持续时间为0的一次性定时器是支持的。
  • 如果目标代码包含类似 await Future.delayed(...) 的代码,它将永久停止。

开始使用

pubspec.yaml 文件中添加依赖:

dev_dependencies:
  manual_clock: ^最新版本号

使用示例

import 'dart:async';
import 'package:test/test.dart';
import 'package:clock/clock.dart';
import 'package:manual_clock/manual_clock.dart';

class ClassDependOnNow {
  final _startTime = clock.now();

  Duration get elapsed => clock.now().difference(_startTime);

  Future<int> someComplicatedTask() async {
    return Future.value(123);
  }
}

void main() {
  test('一个测试用例', () async {
    await withManualClock((clock) async {
      final stopwatch = ClassDependOnNow();
      expect(stopwatch.elapsed, Duration.zero);

      final duration = Duration(minutes: 3);
      clock.elapse(duration);
      expect(stopwatch.elapsed, duration);

      final result = await stopwatch.someComplicatedTask();
      expect(result, 123);

      var fired = false;
      Timer(duration, () {
        fired = true;
      });
      clock.elapse(duration);
      expect(fired, true);
    });
  });
}

更多关于Flutter手动时钟控制插件manual_clock的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter手动时钟控制插件manual_clock的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用manual_clock插件的一个示例代码案例。manual_clock插件允许你手动控制Flutter应用中的时钟时间,这在测试或演示与时间相关的功能时非常有用。

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

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

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

接下来,你可以在你的Flutter应用中使用manual_clock插件。以下是一个简单的示例,展示如何手动控制时间并更新UI:

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

void main() {
  // 使用ManualClock.runApp来包裹你的MaterialApp
  ManualClock.runApp(MyApp());
}

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<int> _animation;

  @override
  void initState() {
    super.initState();

    // 初始化动画控制器,这里我们使用一个固定时间范围来模拟时钟
    _controller = AnimationController(
      duration: const Duration(seconds: 60),  // 假设我们每分钟更新一次时间显示
      vsync: this,
    )..repeat(reverse: true);

    // 创建一个整型动画,从0到59(假设是秒)
    _animation = IntTween(begin: 0, end: 59).animate(_controller);

    // 监听ManualClock的时间变化
    ManualClock.addListener(() {
      // 当时间变化时,重置动画控制器的时间
      final currentTime = ManualClock.now();
      final seconds = currentTime.second;
      _controller.value = seconds / 60.0;  // 将秒转换为0到1的范围,因为我们的动画持续60秒
    });

    // 初始化ManualClock到一个固定时间(可选)
    ManualClock.fixedTime = DateTime(2023, 10, 5, 14, 30, 0);  // 设置为2023年10月5日14:30:00
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Manual Clock Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Current Time:',
              style: TextStyle(fontSize: 20),
            ),
            Text(
              '${ManualClock.now().hour.toString().padLeft(2, '0')}:${ManualClock.now().minute.toString().padLeft(2, '0')}:${ManualClock.now().second.toString().padLeft(2, '0')}',
              style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
            ),
            SizedBox(height: 20),
            Slider(
              value: _controller.value,
              onChanged: (value) {
                // 通过滑块手动控制时间(仅用于演示,实际应用中可能不需要)
                ManualClock.fixedTime = DateTime(
                  ManualClock.now().year,
                  ManualClock.now().month,
                  ManualClock.now().day,
                  ManualClock.now().hour,
                  ManualClock.now().minute,
                  (value * 60).round(),  // 将0-1范围的值转换回秒
                );
              },
              min: 0.0,
              max: 1.0,
              label: '${(_animation.value * 60).round()}',
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 示例:每点击一次按钮,时间前进5秒
          ManualClock.add(const Duration(seconds: 5));
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 使用ManualClock.runApp来包裹MaterialApp,这样我们就可以在整个应用中手动控制时间。
  2. initState中,我们设置了一个动画控制器来模拟时间的流逝(尽管这里主要是为了演示如何监听和更新时间)。
  3. 使用ManualClock.addListener来监听时间的变化,并在时间变化时重置动画控制器的时间。
  4. 使用ManualClock.fixedTime来初始化一个固定时间(可选)。
  5. 使用一个Slider来手动控制时间(仅用于演示)。
  6. 添加了一个浮动按钮,每次点击都会使时间前进5秒。

请注意,这个示例主要用于演示目的,实际应用中可能需要根据具体需求进行调整。

回到顶部