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' }); }); });
关键细节说明
- 异步生成器的作用:
async function*会自动返回符合异步可迭代协议的迭代器,完美匹配aggregatedListAsync的返回类型; - 数据结构对齐:模拟的
mockEntries严格对齐真实API返回的[zone, diskEntry]键值对结构,确保业务逻辑处理一致; - 错误场景模拟:若要测试异常分支,可在异步生成器中抛出错误,比如:
[Symbol.asyncIterator]: async function* () { yield mockEntries[0]; throw new Error('API request failed'); }
内容的提问来源于stack exchange,提问作者achacttn
相关产品推荐
相关产品推荐

