关于 dart-add-unit-test
这是面向 Dart 命令行和后端项目的测试技能,提供单元测试、依赖模拟及覆盖率检查指导。它推荐使用 `package:test` 和 `mocktail`,并以清单组织编写、运行和检查测试的流程。
主要功能
- 01`package:test` 单元测试规范
- 02Arrange-Act-Assert 测试结构
- 03使用 mocktail 或 mockito 模拟依赖
- 04验证模拟对象交互
- 05覆盖率命令与目标
- 06按步骤执行测试的清单
适用场景
- 01测试 Dart 业务逻辑
- 02模拟仓储依赖
- 03验证方法调用及顺序
- 04运行 Dart 或 Flutter 覆盖率检查
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ dhruvanbhalara/ skills --skill dart-add-unit-test安装后在 Claude Code 中输入/dart-add-unit-test确认已加载。
详细介绍
Dart 测试套件
目录
单元测试
使用 package:test 作为 Dart CLI 和后端应用的标准测试库。
- 让测试文件的目录结构与
lib目录一致。测试文件以_test.dart结尾。 - 使用
group()函数对相关测试进行分组。 - 使用
setUp()和tearDown()管理共享测试状态。 - 在 Domain/BLoC 中编写纯逻辑,并将其提取为静态纯函数,以实现 100% 的单元测试覆盖率。
- 使用字符串插值作为测试组名称:
group('$ClassName', ...) - 按照 Arrange-Act-Assert(Given-When-Then)约定组织每项测试:
- Arrange:设置模拟对象、创建实例、准备输入数据。
- Act:调用待测方法。
- Assert:验证输出或副作用。
- 将设置与验证分开,让测试更易读、更易维护。
模拟依赖项
mocktail 与 mockito 的选择
| 标准 | mocktail(推荐) | mockito |
|---|---|---|
| 代码生成 | 无需 | 需要 build_runner |
| 设置速度 | 快(扩展 Mock) | 较慢(注解 + 代码生成) |
| 空安全 | 完全支持 | 完全支持 |
| API 风格 | when(() => mock.method()) | when(mock.method()) |
| 适用场景 | 大多数项目,快速迭代 | API 复杂的大型项目 |
规则:默认使用 mocktail(无需代码生成,设置更快)。只有在复杂 API 存在许多重载、需要使用 @GenerateNiceMocks 时,才使用 mockito。
mocktail 设置(推荐)
import 'package:mocktail/mocktail.dart';
// Create mock: no code generation needed
class MockUserRepository extends Mock implements UserRepository {}
void main() {
late MockUserRepository mockRepo;
setUp(() {
mockRepo = MockUserRepository();
});
test('fetches user successfully', () {
// Arrange
when(() => mockRepo.getUser('1'))
.thenAnswer((_) async => const User(id: '1', name: 'Alice'));
// Act
final user = await mockRepo.getUser('1');
// Assert
expect(user.name, 'Alice');
verify(() => mockRepo.getUser('1')).called(1);
});
}
mockito 设置(代码生成)
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
@GenerateNiceMocks([MockSpec<UserRepository>()])
import 'user_test.mocks.dart'; // Generated by: dart run build_runner build
验证 API
| API | 用途 |
|---|---|
verify(() => mock.method()).called(1) | 断言方法恰好被调用一次 |
verifyNever(() => mock.method()) | 断言方法从未被调用 |
verifyNoMoreInteractions(mock) | 断言没有剩余的未检查交互 |
verifyInOrder([...]) | 断言方法按指定顺序被调用 |
reset(mock) | 清除所有桩和交互 |
注册回退值
对于参数包含自定义类型的方法:
setUpAll(() {
registerFallbackValue(const User(id: '0', name: 'fallback'));
});
测试覆盖率
- 目标是让领域模型和业务逻辑达到 100% 的逻辑覆盖率。
- 使用
dart test --coverage=coverage或flutter test --coverage运行覆盖率检查。 - 有关生成详细 LCOV/HTML 报告的信息,请参阅
dart-coverage技能。
工作流:测试执行
测试 Dart 功能时,请遵循以下顺序工作流。复制此清单以跟踪进度。
任务进度
- 步骤 1:编写单元测试。 专注于核心业务逻辑。确保文件以
_test.dart结尾。 - 步骤 2:生成模拟对象。 如果使用 Mockito,运行
dart run build_runner build来生成模拟对象。 - 步骤 3:运行测试。 执行
dart test。 - 步骤 4:检查覆盖率。 运行
dart test --coverage=coverage并确认达到覆盖率目标。
评论
支持 Markdown