背景
在开发鸿蒙项目时,需要预览某个Component
的UI,但由于数据时后端接口下发的,只能在预览时,临时将值写在本地,运行时再改回实际的数据,这样就比较麻烦,同时后期再次维护这个Component
的UI时,也不能及时预览到UI的效果。
在Android开发中,这种场景可以用xml的tools
来临时模拟UI数据,实际运行时也不会受到影响。
那在鸿蒙中有没有类似的功能呢?答案是有的。
预览数据模拟
官方提供了预览Mock工具@ohos/hamock
,在新建项目时,默认依赖。
json
// 需要在工程或模块的oh-package.json5中添加该依赖,然后重新同步工程
"devDependencies": {
"@ohos/hamock": "1.0.0"
}
利用这个工具的本地类模拟功能,创建一个本地的工具类,传入两个值,一个是预览时的MOCK数据,另一个则是实际运行时获取的值。
实现
- 在src/main/ets项目目录下新建一个名为
MockTools.ets
文件, 示例如下。
js
export default class Mock {
/**
* Mock 数据获取,默认返回实际数据
* @param _mockValue Mock 数据
* @param value 实际数据
* @returns 实际数据
*/
public static value<T>(_mockValue?: T, value?: T): T | undefined {
return value
}
}
- 在src/mock目录下新建一个名为
MockTools.mock.ets
文件, 示例如下。
js
// import local module
import LibDefaultExport from '../main/ets/utils/MockTools';
class DefaultExportMock extends LibDefaultExport {
/**
* Mock 数据获取,默认返回Mock数据
* @param mockValue Mock数据
* @param _value 实际数据
* @returns Mock数据
*/
public static value<T>(mockValue?: T, _value?: T): T | undefined {
return mockValue
}
}
export default DefaultExportMock;
- 在Mock配置文件(src/mock/mock-config.json5)中定义目标Module与Mock实现的替换关系。该替换关系仅会在预览场景下生效。
json
{
"utils/MockTools.ets": {
// 本地module只支持ets/xxx的相对路径,并需明确文件后缀
"source": "src/mock/MockTools.mock.ets"
}
}
运用
在项目某个Component
中,在需要预览Mock的地方传入第一个参数Mock数据,第二个参数传入实际值,例如下面示例中的Text
。
实际值可以不传,例如下面示例中的backgroundColor
设置。
js
import Mock from "../../../utils/MockTools"
@Preview
@Component
export struct TestCtrl {
@Require
data: string = ''
@State
bean?: TestBean = undefined
aboutToAppear(): void {
this.bean = JSON.parse(JSON.stringify(this.data))
}
build() {
Text(Mock.value("标题标题",this.bean?.title)) // 预览显示"标题标题",
.fontWeight(FontWeight.Medium)
.fontSize(17)
.width('100%')
.backgroundColor(Mock.value(Color.Red)) // 在预览时显示背景,增强范围提醒
.padding({ left: 20, right: 20, bottom: 14 })
}
}
hamock的其他能力
Mock Component中的某个方法
被@MockSetup
修饰的方法会在预览时运行,时机会先于组件的aboutToAppear
执行。示例中method1方法为业务方法,在预览时传入值为test
时,会执行Mock,返回值1
。
js
import { MockKit, when, MockSetup } from '@ohos/hamock';
@Entry
@Component
struct Index {
...
@MockSetup
randomName() {
let mocker: MockKit = new MockKit();
let mockfunc: Object = mocker.mockFunc(this, this.method1);
// mock 指定的方法在指定入参的返回值
when(mockfunc)('test').afterReturn(1);
}
...
// 业务场景调用方法
const result = this.method1('test'); // in previewer, result = 1
}
Mock Component中的某个全局属性
同上,需要用@MockSetup
修饰一个方法,在这个方法内,可直接对全局字段进行赋值,预览时显示,实际运行时则不会进行赋值。示例如下。
js
import { MockSetup } from '@ohos/hamock';
@Component
struct Person {
@Prop species: string;
// 在@MockSetup片段中,定义对象属性
@MockSetup
randomName() {
this.species = 'primates'
}
...
// 业务场景调用属性(如果从初始化到调用期间,该属性无变化)
const result = this.species // in previewer, result = primates
}
Mock 系统Component或类
MeasureText
为系统类,在measureText
时返回指定值并打印日志。使用方法和本文Mock工具类一致。
js
import MeasureText from '@ohos.measure'
// 类的mock使用继承(extends)的方式实现
class MockMeasureText extends MeasureText {
// 定义mock实现
static measureText(): number {
console.log('Return value of the mock measureText function')
return 100;
}
};
export default MockMeasureText;