关于 mockito
面向 Dart 和 Flutter 测试开发者的 Mockito 使用指南,介绍何时使用 Mock 以及如何验证交互。内容涵盖 Mock 生成、存根设置、参数匹配与调用验证。
主要功能
- 01选择真实对象、Fake 或 Mock
- 02使用注解生成 Mock
- 03设置返回值和错误存根
- 04验证并捕获交互
- 05重置 Mock 并记录调用
适用场景
- 01使用 build_runner 生成测试 Mock
- 02检查调用次数和参数
- 03设置同步与异步行为存根
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ evanca/ flutter-ai-rules --skill mockito安装后在 Claude Code 中输入/mockito确认已加载。
详细介绍
Mockito 技能
本技能介绍如何在 Dart 和 Flutter 测试中正确使用 mockito 包进行模拟。
1. Mock、Fake 与真实对象
| 用途 | 适用场景 |
|---|---|
| 真实对象 | 实际可行时,优先使用真实对象,而不是 Mock。 |
Fake(extends Fake) | 轻量级自定义实现;只需重写所需方法。如果不需要验证交互,优先使用 Fake,而不是 Mock。 |
Mock(extends Mock) | 仅在需要验证交互(调用次数、参数)或存根动态响应时使用。 |
- 如果可以通过存根数据构造,不要模拟数据模型。
- 只有在测试中有
verify断言时才使用 Mock;否则优先使用真实对象或 Fake。
2. 生成 Mock
@GenerateMocks([MyClass])
// or for nice mocks (return simple legal values for missing stubs):
@GenerateNiceMocks([MockSpec<MyClass>()])
void main() { ... }
dart run build_runner build
- 默认只为
test/下的文件添加 Mock 生成注解。 - 如果需要在
test/之外生成 Mock,请使用build.yaml。 - 不要向继承
Mock的类添加@override方法或实现。 - 不要在 Mock 的构造函数中或 Mock 类内部为响应设置存根——始终在测试中设置存根。
3. 设置存根
final mock = MockCat();
// Return a value
when(mock.sound()).thenReturn('Meow');
// Throw an error
when(mock.sound()).thenThrow(Exception('No sound'));
// Calculate response at call time
when(mock.sound()).thenAnswer((_) => computedValue);
// Return values in sequence
when(mock.sound()).thenReturnInOrder(['Meow', 'Purr']);
- 如果需要特定返回值,使用方法或 getter 之前始终先设置存根。
- 缺少存根时的行为:
@GenerateMocks→ 抛出异常;@GenerateNiceMocks→ 返回一个简单的合法值。 - 使用
throwOnMissingStub(mock)可让任何未设置存根的调用抛出异常。
4. 验证
verify(mock.sound()); // called at least once
verifyNever(mock.eat(any)); // never called
verify(mock.sound()).called(2); // called exactly twice
异步:
await untilCalled(mock.sound()); // wait for the interaction
5. 参数匹配器
// Flexible stubbing
when(mock.eat(any)).thenReturn(true);
when(mock.eat(argThat(isNotNull))).thenReturn(true);
// Named arguments
when(mock.fetch(any, headers: any)).thenReturn(response);
- 不要将
null用作与参数匹配器相邻的参数。 - 对于命名参数,请将
any或argThat用作参数值,而不是参数名。
6. 捕获参数
final captured = verify(mock.eat(captureAny)).captured;
print(captured.last); // last captured argument
使用 captureThat 进行条件捕获。
7. 重置 Mock
reset(mock); // clear all stubs AND interactions
clearInteractions(mock); // clear only recorded interactions
8. 模拟函数类型
要模拟函数类型(例如回调),请定义一个具有所需签名的抽象类,并为其生成 Mock:
abstract class Callback {
void call(String value);
}
@GenerateMocks([Callback])
9. 调试
logInvocations([mock1, mock2]); // print all collected invocations
参考资料
评论
支持 Markdown