渐进式编程课
鸿蒙 目录
第 44 课2026.09.02

单独测试资源关闭失败时,清理函数是否把错误传给调用者。

第 44 课:Hypium清理失败传播测试

  • 日期:2026-09-02
  • 课程序号:第 44 课
  • 知识点:可控拒绝、await 与失败可观察性

用途

单独测试资源关闭失败时,清理函数是否把错误传给调用者。

核心概念

  • 清理函数必须 await 真正的异步关闭,不能提前返回成功。
  • 本课在 it 内捕获故意注入的错误并断言;真实 afterEach 调用清理函数时不吞错。
  • 测试替身只在关闭成功后改变 opened,关闭失败不能伪造已关闭状态。

最小代码或操作示例

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

class ClosingChannel {
  opened: boolean = true;
  async close(fail: boolean): Promise<void> {
    await Promise.resolve();
    if (fail) { throw new Error("close failed"); }
    this.opened = false;
  }
}
async function cleanup(channel: ClosingChannel, fail: boolean): Promise<void> {
  await channel.close(fail);
}
export default function cleanupFailureTest(): void {
  describe("cleanup failure", () => {
    it("propagatesCloseFailure", 0, async () => {
      const channel: ClosingChannel = new ClosingChannel();
      let message: string = "";
      try {
        await cleanup(channel, true);
      } catch (error) {
        message = (error as Error).message;
      }
      expect(message).assertEqual("close failed");
      expect(channel.opened).assertTrue();
    });
  });
}

3~5 分钟练习

在同一 describe 中增加成功关闭用例,确认 await 结束后 opened 为 false。

参考答案

ts
it("closesSuccessfully", 0, async () => {
  const channel: ClosingChannel = new ClosingChannel();
  await cleanup(channel, false);
  expect(channel.opened).assertFalse();
});

与上一课的联系

上一课在 afterEach 等待关闭;本课用独立测试验证该清理操作的失败契约。示例放入已有 Hypium 测试文件并注册到测试入口。