Flutter for OpenHarmony:mockito 单元测试的替身演员,轻松模拟复杂依赖(测试驱动开发必备) 深度解析与鸿蒙适配指南

Flutter for OpenHarmony:mockito 单元测试的替身演员,轻松模拟复杂依赖(测试驱动开发必备) 深度解析与鸿蒙适配指南

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net

在这里插入图片描述

前言

在软件开发中,单元测试(Unit Testing)是保证代码质量的基石。然而,在测试某个具体的业务逻辑(如 UserService)时,我们往往会遇到各种外部依赖,比如数据库查询、网络请求、设备传感器等。

如果直接调用真实的 DatabaseHttpClient,不仅测试速度慢,而且容易因为网络抖动或环境问题导致测试失败。此外,我们很难复现一些极端场景(如 500 服务器错误、数据库连接超时)。

Mockito 就是为了解决这个问题而生的。它允许我们创建对象的 Mock(替身),并精确控制这些替身的行为(Stubbing)和验证它们的交互(Verification)。

在 OpenHarmony 应用开发中,使用 mockito 可以让我们在开发机(Host)上就能快速验证大部分业务逻辑,通过后再部署到鸿蒙真机进行集成测试,极大地提高了开发效率。

一、核心概念与工作原理

1.1 什么是 Mock?

Mock 对象是真实对象的“傀儡”。它继承自真实类,但不会执行真实类的任何代码。相反,它记录了所有对它的调用,并根据你的配置返回预设的值。

1.2 Mockito 的黑魔法:代码生成 (Codegen)

早期版本的 Mockito 依赖 noSuchMethod 和反射(Mirrors),但在 Flutter 中禁止使用反射(为了 AOT 优化)。因此,现在的 mockito 配合 build_runner 使用,在编译时生成 Mock 类。

@GenerateMocks

生成

使用

验证

RealClass.dart

build_runner

RealClass.mocks.dart

单元测试

Mock 对象

1.3 核心操作三部曲

  1. Stubbing (桩): when(mock.method()).thenReturn(value) —— “当调用这个方法时,请返回这个值”。
  2. Execution (执行): 运行被测代码,被测代码会调用 Mock 对象。
  3. Verification (验证): verify(mock.method()) —— “验证这个方法是否被调用过,且参数正确”。

二、集成与基础用法

2.1 添加依赖

mockito 通常只在 dev_dependencies 中使用。

dev_dependencies:flutter_test:sdk: flutter mockito: ^5.6.3 build_runner: ^2.4.0 

2.2 定义被测类

假设我们有一个从 API 获取用户信息的服务:

// user_api.dartimport'dart:convert';import'package:http/http.dart'as http;classUserApi{finalhttp.Client client;UserApi(this.client);Future<String>fetchUserName(int id)async{final response =await client.get(Uri.parse('https://api.example.com/users/$id'));if(response.statusCode ==200){returnjsonDecode(response.body)['name'];}else{throwException('Failed to load user');}}}

2.3 生成 Mock 类

创建一个测试文件,使用注解 @GenerateMocks

// user_api_test.dartimport'package:mockito/annotations.dart';import'package:http/http.dart'as http;import'package:flutter_test/flutter_test.dart';import'package:mockito/mockito.dart';import'user_api.dart';// 引入生成的文件import'user_api_test.mocks.dart';@GenerateMocks([http.Client])voidmain(){// ...}

然后在终端运行命令生成代码:

flutter pub run build_runner build 

2.4 编写测试用例

voidmain(){ late MockClient mockClient; late UserApi userApi;setUp((){ mockClient =MockClient(); userApi =UserApi(mockClient);});test('returns name if the http call completes successfully',()async{// 1. Stubbing: 模拟 http.Client 返回 200 OKwhen(mockClient.get(Uri.parse('https://api.example.com/users/1'))).thenAnswer((_)async=>http.Response('{"name": "张三"}',200));// 2. Executionfinal name =await userApi.fetchUserName(1);// 3. Verification: 验证结果expect(name,'张三');// 验证 get 方法确实被调用了一次verify(mockClient.get(Uri.parse('https://api.example.com/users/1'))).called(1);});test('throws an exception if the http call completes with an error',(){// 1. Stubbing: 模拟返回 404when(mockClient.get(Uri.parse('https://api.example.com/users/1'))).thenAnswer((_)async=>http.Response('Not Found',404));// 2. Execution & Verificationexpect(userApi.fetchUserName(1), throwsException);});}
在这里插入图片描述


在这里插入图片描述

三、进阶技巧

3.1 参数匹配 (Argument Matchers)

有时候我们不关心具体的参数值,只关心参数类型。

// 匹配任何 Uriwhen(mockClient.get(any)).thenAnswer(...)// 命名参数匹配when(obj.method(foo:anyNamed('foo'))).thenReturn(...)// 捕获参数进行验证test('captures arguments',(){// ... trigger ...// 验证调用并捕获参数final captured =verify(mockClient.get(captureAny)).captured;print(captured.first);// 输出 Uri 对象});

3.2 顺序验证 (InOrder)

验证多个方法的调用顺序。

test('verify interaction order',(){final cat =MockCat(); cat.eat(); cat.sleep();verifyInOrder([ cat.eat(), cat.sleep(),]);});

3.3 模拟异常与重试逻辑

开发鸿蒙应用时,网络波动是常态。我们可以 Mock 抛出异常来测试 App 的重试机制是否工作。

test('测试重试逻辑',()async{// 第一次调用抛出异常,第二次成功when(mockApi.getData()).thenThrow(Exception('Network Error')).thenAnswer((_)async=>'Success');// 调用业务逻辑...});
在这里插入图片描述

四、OpenHarmony 适配与实战:模拟鸿蒙原生通道 (Platform Channel)

在 OpenHarmony 开发中,我们经常需要通过 MethodChannel 调用系统的原生能力(如获取电池电量、调用 HiLog)。在写 UI 测试或逻辑测试时,我们不能真的去调底层,因为测试环境可能只是一个 Dart VM。

我们可以 Mock MethodChannel 的 handlers。

4.1 场景:电池电量获取

假设我们有一个 BatteryService

import'package:flutter/services.dart';classBatteryService{staticconst platform =MethodChannel('ohos.samples.battery');Future<String>getBatteryLevel()async{try{final int result =await platform.invokeMethod('getBatteryLevel');return'当前电量 $result%';}onPlatformExceptioncatch(e){return"获取电量失败: '${e.message}'.";}}}

4.2 编写测试

Flutter 官方提供了 TestDefaultBinaryMessenger 来模拟底层消息。但在单元测试层面,mockito 也可以派上用场,或者我们可以直接 mock 对 BatteryService 的依赖。

这里我们展示如何使用 mockito 测试一个依赖 BatteryServiceViewModel

// battery_view_model.dartclassBatteryViewModel{finalBatteryService _service;String status ='未知';BatteryViewModel(this._service);Future<void>refresh()async{ status =await _service.getBatteryLevel();}}// battery_view_model_test.dart@GenerateMocks([BatteryService])import'battery_view_model_test.mocks.dart';voidmain(){test('ViewModel updates status from service',()async{final mockService =MockBatteryService();final viewModel =BatteryViewModel(mockService);// Stubbing: 模拟鸿蒙设备返回了 100% 电量when(mockService.getBatteryLevel()).thenAnswer((_)async=>'当前电量 100%');await viewModel.refresh();expect(viewModel.status,'当前电量 100%');});}

4.3 为什么这对鸿蒙开发重要?

鸿蒙设备的 API(如 @ohos.batteryInfo)只能在真机或模拟器运行。如果你的 Dart 代码中混杂了原生调用,一旦离开真机环境就会报错。

通过 Dependency Injection (依赖注入) 配合 Mockito,你可以让 Dart 业务逻辑与鸿蒙原生 API 解耦。

  • 开发时:在 PC 上运行测试,Mock 掉鸿蒙 API,开发效率极高。
  • 运行时:注入真实的 BatteryService,调用鸿蒙底层。

五、总结

mockito 是测试驱动开发(TDD)的利器。它让我们能够隔离关注点,专注于当前模块的逻辑,而不必担心外部世界的复杂性。

对于 OpenHarmony 开发者,掌握 Mock 技术意味着你可以构建出架构更清晰、可测试性更强的应用。无论是模拟网络、数据库,还是模拟鸿蒙特有的系统服务,mockito 都能帮你轻松搞定。

最佳实践

  1. 多用接口:针对 Interface 编程,而不是针对 Implementation。Mock 接口比 Mock 具体类更容易且风险更小。
  2. 不要 Mock 数据类:对于 DTO(Data Transfer Object)或简单的实体类,直接 new 一个真的对象,不要 Mock 它。
  3. 保持测试简单:如果你的 Mock 配置(when…then…)写了几十行,说明被测代码可能耦合太重,需要重构了。

六、完整实战示例:带超时的网络请求模拟器

import'package:mockito/mockito.dart';import'package:test/test.dart';// 1. 业务接口abstractclassNetworkService{Future<String>request(String path);}// 2. 模拟生成的 Mock 类classMockNetworkServiceextendsMockimplementsNetworkService{@overrideFuture<String>request(String? path)=>super.noSuchMethod(Invocation.method(#request,[path]), returnValue:Future.value(""),)asFuture<String>;}// 3. 业务逻辑类classDataManager{finalNetworkService _service;DataManager(this._service);Future<String>safeRequest()async{try{// 模拟 2 秒延迟外的逻辑returnawait _service.request('/data').timeout(Duration(seconds:1));}catch(e){return"Timeout or Error";}}}voidmain(){test('模拟请求超时场景',()async{final mockService =MockNetworkService();final manager =DataManager(mockService);// Stubbing: 让请求延迟 2 秒返回,从而触发业务层的超时when(mockService.request(any)).thenAnswer((_)async{awaitFuture.delayed(Duration(seconds:2));return"Delayed Data";});final result =await manager.safeRequest();expect(result,"Timeout or Error");verify(mockService.request('/data')).called(1);});}
在这里插入图片描述

Read more

OpenClaw 配置本地 Ollama 模型完整指南:零成本打造全离线个人 AI 助理

OpenClaw 配置本地 Ollama 模型完整指南:零成本打造全离线个人 AI 助理(2026 最新版·含 Auth 配置) 大家好,我是你的 AI 技术博主。今天我们来聊一个 2026 年最火的本地 AI 助理项目——OpenClaw。它能帮你清理收件箱、发邮件、管理日历、处理文件、集成 Telegram/WhatsApp,甚至执行复杂任务,而且完全跑在你自己的电脑上。 配合 Ollama 运行本地模型(如 Qwen3、Qwen2.5、GLM-4.7、Llama3.3 等),你就可以实现真正零费用、零网络依赖、全隐私保护的智能体体验。官方从 Ollama 0.17

By Ne0inhk
Topaz Video AI v7.1.1_Win中文_视频修复_汉化便携版安装教程

Topaz Video AI v7.1.1_Win中文_视频修复_汉化便携版安装教程

软件下载 【名称】:****人工智能视频画质增强和修复软件Topaz Video AI v7.1.1 【大小】:****245M 【语言】:简体中文 【安装环境】:Win10/Win11 【夸克网盘下载链接】(务必手机注册): 夸克 【网站下载链接】: 其他网盘 软件介绍 Topaz Video AI(曾用名:Topaz Vide Enhance AI)是一款运用了AI人工智能技术的视频修复增强软件,使用神经网络进行训练的,该神经网络分析成千上万对视频,以了解通常如何丢失细节,够推断出更多细节,从而在单个视频剪辑中提供大量信息的情况下呈现出更加逼真的外观,可以将视频放大至8K分辨率,并提供真实的细节和动作一致性,放大后的视频不会出现模糊的情况,帮您制作漂亮清晰的高档视频素材。 软件安装 **1、 下载解压安装包 **exe格式的压缩包如何解压??? 2、直接管理员身份运行【TopazVideoAIPortable.exe】就行 3、软件界面

By Ne0inhk
AI 绘画神器爆改指南:kohya_ss 一文速通 LoRA 训练与对比解析!

AI 绘画神器爆改指南:kohya_ss 一文速通 LoRA 训练与对比解析!

目 录 * 前言 * kohya_ss * 安装步骤 * 测试 * 风吟kohya_ss-v2 * stable diffusion模型微调方法 * 结果 * kohya_ss 总结 * 工具概览 * 本地安装 vs 云端使用 * Stable Diffusion 微调方法对比 * LoRA 训练的关键参数 * 总结 前言 上一篇文章已经讲了ComfyUI——Windows 结合最新版 ComfyUI 部署图像大模型详细步骤(含Web和本地) 这篇文章来聊一聊关于kohya_ss工具 kohya_ss是一个专为Stable Diffusion模型训练设计的工具,主要用于使用LoRA方法对模型进行微调和训练。 功能与用途 * LoRA模型训练:kohya_ss允许用户通过LoRA(低秩适应)方法对Stable Diffusion模型进行微调。这种方法可以在不修改原始模型参数的情况下,插入新的网络层,从而实现轻量化的模型调校。 * 可视化界面:该工具提供了一个用户友好的可视化界面,

By Ne0inhk
人工智能:计算机视觉的基础与应用

人工智能:计算机视觉的基础与应用

第十二篇:计算机视觉的基础与应用 学习目标 💡 理解计算机视觉的基本概念和重要性 💡 掌握计算机视觉中的图像处理技术、特征提取方法、常用模型与架构 💡 学会使用计算机视觉库(OpenCV、PIL、PyTorch、TensorFlow)进行图像处理、特征提取和模型训练 💡 理解图像分类、目标检测、语义分割等任务的实现方法 💡 通过实战项目,开发一个完整的计算机视觉应用 重点内容 * 计算机视觉的基本概念 * 图像处理技术(图像预处理、增强、滤波) * 特征提取方法(HOG、SIFT、ORB) * 常用模型与架构(LeNet、AlexNet、VGG、ResNet、YOLO) * 实战项目:计算机视觉应用开发(图像分类、目标检测等) 一、计算机视觉基础 1.1 计算机视觉的基本概念 计算机视觉(Computer Vision)是人工智能的一个重要分支,它涉及计算机与图像之间的交互。其目标是让计算机能够理解和解释图像内容,

By Ne0inhk