渐进式编程课
鸿蒙 目录
第 25 课2026.08.06

适用场景:被测对象依赖网络、数据库等外部服务,希望单元测试快速、稳定且不访问真实环境

第 25 课:Hypium 测试替身与依赖注入

  • 日期:2026-08-06
  • 课程序号:第 25 课
  • 知识点:用 Fake 服务替换真实依赖,并验证调用参数与返回结果
  • 适用场景:被测对象依赖网络、数据库等外部服务,希望单元测试快速、稳定且不访问真实环境

承接上一课:数据表驱动测试解决了“同一规则如何覆盖多组输入”;本课解决“被测逻辑依赖外部服务时如何隔离测试”。

核心概念

  • 依赖注入:被测对象不在内部创建具体服务,而是从构造函数接收接口实现。
  • Fake(测试替身):实现同一接口,返回可控数据,并记录收到的参数。
  • 测试既要断言业务结果,也可断言依赖是否收到正确参数;无需发起真实请求。

最小 ArkTS / Hypium 示例

ts
import { describe, expect, it } from '@ohos/hypium';

interface UserService {
  queryName(userId: number): Promise<string>;
}

class UserProfile {
  constructor(private userService: UserService) {}

  async getGreeting(userId: number): Promise<string> {
    const name: string = await this.userService.queryName(userId);
    return `你好,${name}`;
  }
}

class FakeUserService implements UserService {
  lastUserId: number = -1;

  queryName(userId: number): Promise<string> {
    this.lastUserId = userId;
    return Promise.resolve('小鸿');
  }
}

export default function userProfileTest(): void {
  describe('UserProfile', () => {
    it('usesUserIdAndReturnsGreeting', 0, async () => {
      const fakeService: FakeUserService = new FakeUserService();
      const profile: UserProfile = new UserProfile(fakeService);

      const greeting: string = await profile.getGreeting(1001);

      expect(fakeService.lastUserId).assertEqual(1001);
      expect(greeting).assertEqual('你好,小鸿');
    });
  });
}

UserProfile 只依赖 UserService 接口。生产环境可以注入真实实现,测试中则注入 FakeUserService,因此测试结果完全可控。

3~5 分钟练习

让 FakeUserService 的返回姓名可配置:通过构造函数接收 name,然后在测试中传入 小明,验证结果为 你好,小明。

参考答案

ts
class FakeUserService implements UserService {
  lastUserId: number = -1;

  constructor(private name: string) {}

  queryName(userId: number): Promise<string> {
    this.lastUserId = userId;
    return Promise.resolve(this.name);
  }
}

const fakeService: FakeUserService = new FakeUserService('小明');
const profile: UserProfile = new UserProfile(fakeService);
const greeting: string = await profile.getGreeting(1001);
expect(greeting).assertEqual('你好,小明');

与上一课的联系

上一课用数据表控制多组输入与期望值;本课进一步用 Fake 控制外部依赖的行为。二者可以组合:把不同 Fake 返回值写入数据表,集中验证多种服务响应下的业务结果。