鸿蒙应用开发实战【83】— 单元测试Hypium框架实战

本文是「号码助手全栈开发系列」第 83 篇,持续更新中…
开源社区:https://openharmonycrossplatform.csdn.net


前言

HarmonyOS 应用测试推荐使用 Hypium(原名 JSUnit)测试框架。项目 oh-package.json5 中已包含 @ohos/hypium 依赖。本篇从 DAO 层的单元测试实战出发,讲解 Hypium 的测试编写、运行和断言技巧。

本篇涵盖:Hypium 测试框架基础结构、describe + it + expect 测试三要素、DAO 层单元测试实战、数据库测试的 beforeEach/afterEach 生命周期、mock 数据策略、测试套件运行配置。

在这里插入图片描述


一、Hypium 基础

1.1 测试文件结构

// entry/src/ohosTest/ets/test/CardDao.test.ets
import { describe, it, expect } from '@ohos/hypium'
import { CardDao } from 'entry/src/main/ets/features/data/CardDao'
import { DatabaseService } from 'entry/src/main/ets/features/data/DatabaseService'

export default function cardDaoTest() {
  describe('CardDao 测试', () => {
    beforeEach(() => {
      // 每个测试用例前执行
    })

    afterEach(() => {
      // 每个测试用例后执行
    })

    it('create 应返回新记录的 id', 0, () => {
      // 测试逻辑
    })
  })
}

1.2 断言 API

expect(result).assertEqual(expected)
expect(result).assertTrue()
expect(result).assertFalse()
expect(result).assertNull()
expect(result).assertNotNull()
expect(result).assertInstanceOf(Type)
expect(callback).assertFail()  // 期望抛出异常

二、DAO 层单元测试实战

2.1 测试配置

// ohosTest 模块的 build-profile.json5
{
  "targets": [
    { "name": "default" },
    { "name": "ohosTest" }  // 测试目标
  ]
}

2.2 CardDao 测试

describe('CardDao', () => {
  const demoCard: CardEntity = {
    label: '卡1',
    phone_number: '13800138000',
    carrier: '中国移动',
    remark: '测试卡号',
    color: 'blue',
    sort_order: 0,
    created_at: Date.now(),
    updated_at: Date.now()
  }

  let createdId: number = 0

  it('create 应成功并返回ID', 0, async () => {
    createdId = await CardDao.create(demoCard)
    expect(createdId).assertTrue(createdId > 0)
  })

  it('findById 应返回正确数据', 0, async () => {
    const card = await CardDao.findById(createdId)
    expect(card).assertNotNull()
    expect(card!.label).assertEqual('卡1')
    expect(card!.phone_number).assertEqual('13800138000')
    expect(card!.color).assertEqual('blue')
  })

  it('update 应修改字段', 0, async () => {
    await CardDao.update({
      id: createdId, ...demoCard,
      remark: '已更新备注',
      updated_at: Date.now()
    })
    const updated = await CardDao.findById(createdId)
    expect(updated!.remark).assertEqual('已更新备注')
  })

  it('deleteById 应删除记录', 0, async () => {
    await CardDao.deleteById(createdId)
    const card = await CardDao.findById(createdId)
    expect(card).assertNull()
  })
})

2.3 AppBindingDao 测试

describe('AppBindingDao', () => {
  let cardId: number = 0

  beforeEach(async () => {
    // 先创建一张卡号作为外键
    cardId = await CardDao.create({
      label: '测试卡', phone_number: '13900001111',
      carrier: '中国联通', remark: '', color: 'blue',
      sort_order: 0, created_at: Date.now(), updated_at: Date.now()
    })
  })

  afterEach(async () => {
    // 清理数据
    const all = await AppBindingDao.listByCardId(cardId)
    const ids = all.map(b => b.id ?? 0)
    await AppBindingDao.deleteMany(ids)
    await CardDao.deleteById(cardId)
  })

  it('batchUpdateStatus 应批量更新状态', 0, async () => {
    const now = Date.now()
    const id1 = await AppBindingDao.create({ app_name: '微信', card_id: cardId, ... })
    const id2 = await AppBindingDao.create({ app_name: '支付宝', card_id: cardId, ... })

    await AppBindingDao.batchUpdateStatus([id1, id2], '待换绑', now)

    const w1 = await AppBindingDao.findById(id1)
    const w2 = await AppBindingDao.findById(id2)
    expect(w1!.status).assertEqual('待换绑')
    expect(w2!.status).assertEqual('待换绑')
  })
})

三、测试运行

# DevEco Studio 中运行
# 1. 选择 ohosTest 目标
# 2. 右键测试方法 → Run

# 命令行运行
hvigorw --mode module -p module=entry -p product=default -p buildMode=debug runOhosTests

小结

要点 说明 对应代码
测试框架 @ohos/hypium:describe / it / expect import { describe, it, expect }
测试目标 build-profile.json5 中配置 ohosTest "name": "ohosTest"
生命周期 beforeEach(创建数据)→ 测试 → afterEach(清理数据) beforeEach(async () => {})
DAO 测试 创建 → 查询 → 更新 → 删除 完整 CRUD 验证 CRUD 四步断言
外键依赖 测试 binding 前先创建 card(外键) cardId = await CardDao.create(...)
清理策略 afterEach 中按反序删除 先删 binding 再删 card

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐