HarmonyOS鸿蒙Next中如何实现单元测试的 Mock(如模拟网络请求、传感器数据)?

HarmonyOS鸿蒙Next中如何实现单元测试的 Mock(如模拟网络请求、传感器数据)? 我们用 Hypium 写测试,但业务逻辑依赖 @ohos.net.http@ohos.sensor。有没有类似 Jest 的 jest.mock() 机制来拦截系统 API?

4 回复

@ohos/hypium 1.0.1版本开始,单元测试框架支持Mock能力。配置方式参考发布方式

使用Mock能力时必须导入Mock能力模块: MockKit,when,开发者可根据实际需求导入对应模块。

例如:import { describe, expect, it, MockKit, when } from ‘@ohos/hypium’

参考单元测试Mock能力

示例代码1:使用afterReturn/afterReturnNothing设置预期返回值:

import { describe, expect, it, MockKit, when } from '[@ohos](/user/ohos)/hypium';

class ClassName {
  constructor() {
  }

  method_1(arg: string) {
    return '888888';
  }
}
export default function afterReturnTest() {
  describe('afterReturn_sample', () => {
    it('afterReturnTest', 0, () => {
      // 创建一个Mock能力的对象MockKit
      let mocker: MockKit = new MockKit();
      // 初始化ClassName的对象claser,作为被Mock的对象实例
      let claser: ClassName = new ClassName();
      // 进行Mock操作,对ClassName类的method_1函数进行Mock
      let mockfunc: Function = mocker.mockFunc(claser, claser.method_1);
      // 期望claser.method_1函数被Mock后, 以'testA'为入参时调用函数返回结果'1',以'testB''为入参时调用函数返回结果undefined
      when(mockfunc)('testA').afterReturn('1');
      when(mockfunc)('testB').afterReturnNothing();
      // 对Mock后的函数进行断言,看是否符合预期。分别传入参数'testA'和'testB'时,应该返回自定义的预期结果1和undefined
      expect(claser.method_1('testA')).assertEqual('1'); // 断言执行通过
      expect(claser.method_1('testB')).assertUndefined(); // 断言执行通过
    })
  })
}

更多关于HarmonyOS鸿蒙Next中如何实现单元测试的 Mock(如模拟网络请求、传感器数据)?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


Hypium 不支持自动 Mock 系统模块,但可通过以下方式实现:

  • 依赖注入:将系统 API 封装为服务类(如 HttpService),在测试时传入 Mock 实现;
  • 手动替换:在测试前重写模块方法(需关闭 ArkTS 严格模式);
// 测试前
const originalRequest = http.request;
http.request = (options) => Promise.resolve(mockResponse);
// 测试后恢复
http.request = originalRequest;

在HarmonyOS Next中,可通过ArkTS的单元测试框架实现Mock。使用@Mock装饰器模拟依赖,例如网络请求或传感器数据。通过mock方法替换实际接口,返回预设数据。

在HarmonyOS Next中,Hypium测试框架目前不直接提供类似Jest的全局jest.mock()自动模拟机制。对于@ohos.net.http@ohos.sensor这类系统API的模拟,主要依赖依赖注入和接口抽象的设计模式来实现。

核心方法是面向接口编程依赖注入。具体操作如下:

  1. 抽象与接口定义:将网络请求和传感器操作封装到自定义的类或接口中。例如,创建INetworkServiceISensorService接口,定义fetchData()getSensorData()等方法。
  2. 实现具体服务:创建实现上述接口的具体类(如HttpNetworkServiceDeviceSensorService),在这些类内部调用真实的@ohos.net.http@ohos.sensor模块。
  3. 依赖注入:在业务代码中,通过构造函数、属性或方法参数等方式,注入接口类型(如INetworkService)的依赖,而非直接依赖具体实现。
  4. 创建Mock实现:为测试编写实现了相同接口的Mock类(如MockNetworkServiceMockSensorService)。在这些Mock类中,你可以硬编码返回预期的数据或模拟异常,而无需调用真实系统API。
  5. 测试中替换:在Hypium测试用例中,创建被测对象时,注入Mock实现(如MockNetworkService的实例)来代替真实实现。这样,当测试执行业务逻辑时,调用的将是你的Mock对象,从而隔离了系统依赖。

示例结构

  • src/main/ets/services/INetworkService.ets (接口)
  • src/main/ets/services/HttpNetworkService.ets (真实实现)
  • src/main/ets/services/MockNetworkService.ets (Mock实现)
  • 在测试文件中,构造被测对象时使用new MockNetworkService()

对于无法轻易抽象的系统级调用(例如直接散落在代码中的模块导入),需要重构代码使其可测试。Hypium框架本身更侧重于测试用例的组织、断言和异步处理,Mock机制需要依靠这种代码设计模式来实现。

回到顶部