位置:首页 > Dart > Mockito核心打桩规则详解与使用要点

Mockito核心打桩规则详解与使用要点

时间:2026-08-20  |  作者:318050  |  阅读:0

掌握 mockito 中不同的“打桩 (Stubbing)”技巧,是写出高质量单元测试的关键。

`mockito` 的核心“打桩”规则

when(...).thenAnswer(...) 只是其中一种方式。

实际上,mockito 提供了一套非常灵活的 API,用来规定 Mock 对象在被调用时的行为。

最常用、最重要的规则主要有以下几种。

mockito 的核心“打桩”规则

假设我们有一个 mockRepository

它有一个方法 String findUser(int id)

1. thenReturn - 返回一个具体的值

这是最常用、最简单的规则。

它规定当方法被调用时,直接返回一个预设好的值。

使用场景

  • 方法返回值可以直接创建。
  • 返回值是简单对象,如 Stringintbool
  • 或者返回一个你自己创建的模型实例。

代码示例

// 规定:当 findUser 被以参数 1 调用时,返回字符串 '张三'
when(mockRepository.findUser(1)).thenReturn('张三');

// 规定:当 findUser 被以任何整数参数调用时,返回字符串 '默认用户'
// an_y 是 mockito 提供的匹配器,表示“任何值”
when(mockRepository.findUser(any)).thenReturn('默认用户');

// 规定:当一个返回 Future 的方法被调用时,返回一个已完成的 Future
when(mockRepository.syncFromRemote()).thenReturn(Future.value()); 

2. thenThrow - 抛出一个异常

这个规则用于测试代码中的错误处理逻辑。

使用场景

  • 模拟网络请求失败。
  • 模拟数据库读取错误。
  • 模拟文件未找到等异常情况。

代码示例

// 规定:当 findUser 被以参数 -1 调用时,抛出一个 Exception
when(mockRepository.findUser(-1)).thenThrow(Exception('用户ID无效'));

// 测试代码就可以这样写:
expect(
  () => userManager.getUserName(-1), 
  throwsException
);

3. thenAnswer - 执行一个函数并返回其结果

这是最强大、最灵活的规则。

你可以提供一个函数。当 Mock 方法被调用时,mockito 会执行这个函数,并将函数返回值作为 Mock 方法的返回值。

使用场景

  • 返回值是一个 FutureStream 时,这是最常见的用法。
  • 返回值需要根据传入参数动态计算时。
  • 希望在方法被调用时执行一些额外逻辑时,比如打印日志。

代码示例

// 规定:当 syncFromRemote 被调用时,执行一个异步函数,并返回一个空的 Future
// 这是您问题中的例子,非常适合异步方法
when(mockRepository.syncFromRemote()).thenAnswer((_) async => {});

// 规定:当 findUser 被调用时,根据传入的 id 动态返回一个名字
when(mockRepository.findUser(any)).thenAnswer((invocation) {
  // invocation 对象包含了调用的所有信息,包括参数
  final int id = invocation.positionalArguments.first;
  return '用户 $id';
});

// 使用
print(mockRepository.findUser(101)); // 会输出: '用户 101'

4. thenCallRealMethod - 调用真实的原始方法

使用场景

这在使用 spy 时相当有用。

spy 属于特殊的Mock对象,它会对真实对象进行“包装”。

通常情况下,调用 spy 的方法会执行真实的方法。

但你也可以利用 when 来覆盖其中某些方法的行为。

thenCallRealMethod 则能让被覆盖的方法恢复其原本的真实行为。

代码示例

// 1. 创建一个真实的对象和一个 spy
final realRepo = RealRepository();
final spyRepo = spy(realRepo);

// 2. 默认情况下,spy 会调用真实方法
spyRepo.someMethod(); // 执行 RealRepository.someMethod()

// 3. 我们可以覆盖某个方法的行为
when(spyRepo.someMethod()).thenReturn('假的返回值');
spyRepo.someMethod(); // 返回 '假的返回值'

// 4. 现在,我们可以让它恢复真实的行为
when(spyRepo.someMethod()).thenCallRealMethod();
spyRepo.someMethod(); // 再次执行 RealRepository.someMethod()

总结

规则作用最常用场景
thenReturn(value)直接返回一个预设的值同步方法,返回简单对象
thenThrow(error)直接抛出一个预设的异常测试错误处理和异常流程
thenAnswer(function)执行一个函数并返回其结果异步方法 (Future),或需要根据参数动态返回值的场景
thenCallRealMethod()调用被包装的真实方法spy 配合使用,用于临时恢复真实行为

掌握这四种核心的“打桩”规则,您就能够非常自如地为几乎所有场景编写出简洁、健壮的单元测试了。

来源:整理自互联网
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多