You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jest模拟异步可迭代对象失败:无法遍历aggregatedListAsync

解决Jest模拟google-cloud/compute中aggregatedListAsync异步可迭代对象的问题

问题根源

aggregatedListAsync返回的是异步可迭代对象,而非Promise或普通数组:

  • 用mockResolvedValue会让方法返回Promise,for await...of无法遍历Promise,触发“not async iterable”错误;
  • 用mockReturnValue但返回普通对象/数组,因未实现Symbol.asyncIterator协议,触发“.for is not iterable”错误。

解决方案:模拟符合异步可迭代协议的返回值

通过**异步生成器(async generator)**构造符合要求的模拟数据,让aggregatedListAsync返回实现了Symbol.asyncIterator的对象。

示例代码

假设你的业务函数如下:

// your-module.js
const { DisksClient } = require('@google-cloud/compute');

async function getAllDisks(projectId) {
  const client = new DisksClient();
  const allDisks = [];
  
  for await (const [zone, diskEntry] of client.aggregatedListAsync({ project: projectId })) {
    if (diskEntry.disks) {
      allDisks.push(...diskEntry.disks);
    }
  }
  
  return allDisks;
}

module.exports = getAllDisks;

对应的Jest测试代码:

// your-module.test.js
const { DisksClient } = require('@google-cloud/compute');
const getAllDisks = require('./your-module');

// 构造模拟的异步可迭代磁盘数据
function createMockAggregatedData() {
  // 模拟真实返回的[zone, diskEntry]结构
  const mockEntries = [
    ['us-central1-a', { disks: [{ name: 'disk-01', sizeGb: '10' }] }],
    ['us-central1-b', { disks: [{ name: 'disk-02', sizeGb: '20' }, { name: 'disk-03', sizeGb: '30' }] }],
    ['us-central1-c', {}], // 模拟无磁盘的可用区
  ];

  // 返回符合异步可迭代协议的对象
  return {
    [Symbol.asyncIterator]: async function* () {
      for (const entry of mockEntries) {
        yield entry;
      }
    },
  };
}

// 全局模拟DisksClient类
jest.mock('@google-cloud/compute', () => ({
  DisksClient: jest.fn().mockImplementation(() => ({
    aggregatedListAsync: jest.fn().mockReturnValue(createMockAggregatedData()),
  })),
}));

describe('getAllDisks', () => {
  it('应收集所有可用区的磁盘数据', async () => {
    const result = await getAllDisks('test-project');
    
    expect(result).toEqual([
      { name: 'disk-01', sizeGb: '10' },
      { name: 'disk-02', sizeGb: '20' },
      { name: 'disk-03', sizeGb: '30' },
    ]);
    
    // 验证方法调用参数
    const client = new DisksClient();
    expect(client.aggregatedListAsync).toHaveBeenCalledWith({ project: 'test-project' });
  });
});

关键细节说明

  1. 异步生成器的作用:async function*会自动返回符合异步可迭代协议的迭代器,完美匹配aggregatedListAsync的返回类型;
  2. 数据结构对齐:模拟的mockEntries严格对齐真实API返回的[zone, diskEntry]键值对结构,确保业务逻辑处理一致;
  3. 错误场景模拟:若要测试异常分支,可在异步生成器中抛出错误,比如:
    [Symbol.asyncIterator]: async function* () {
      yield mockEntries[0];
      throw new Error('API request failed');
    }
    

内容的提问来源于stack exchange,提问作者achacttn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:28:27