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

TypeScript中Jest SpyOn可迭代对象报错‘createDiscounts不可迭代’的解决

如何Mock可迭代对象解决‘createDiscounts is not iterable’测试错误

我想为一个简单的TypeScript类监视(spy on)一个普通数组,但运行测试时出现错误提示‘createDiscounts is not iterable’,请问如何mock可迭代对象?

原业务代码(discounts.ts)

// discounts.ts
export function createDiscounts() {
  const discounts: number[] = [0.5, 0.4, 0.7, 0.9]
  return discounts.entries()
}

export class ProcessDiscountedItemsService {
  // 注:原代码中applyDiscounts里的discounts未定义,推测需调用createDiscounts()
  applyDiscounts = (items: OrderItem) => {
    for(let [number, discount] of createDiscounts()){
      // do logic
    }
  }
}

测试代码(尝试版)

import * as DiscountUtil from '../discounts.ts'
describe('Process discount', () => {
  const service = new ProcessDiscountedItemsService()
  it('process item discounts verify', () =>{
    const items = /* 你的测试数据 */
    const spy = jest.spyOn(DiscountUtil, 'createDiscounts') as jest.Mock
    const iteratable = [0.5, 0.4, 0.7, 0.9].entries()
    service.applyDiscounts(items)
  })
})

问题分析

当前测试代码存在两个核心问题:

  • 未给mock的createDiscounts函数指定返回值,默认返回undefined,而undefined不是可迭代对象,触发错误。
  • 原业务代码中applyDiscounts方法的discounts变量未定义,需修正为调用createDiscounts()获取可迭代对象。

正确Mock方案

方案1:直接返回数组entries迭代器

直接生成符合要求的迭代器作为mock返回值:

import * as DiscountUtil from '../discounts.ts'
describe('Process discount', () => {
  const service = new ProcessDiscountedItemsService()
  it('process item discounts verify', () =>{
    const items = /* 你的测试数据 */
    // 创建要mock的可迭代对象
    const mockDiscountEntries = [0.1, 0.2].entries()
    // 监视createDiscounts并指定返回值
    const spy = jest.spyOn(DiscountUtil, 'createDiscounts') as jest.Mock
    spy.mockReturnValue(mockDiscountEntries)
    
    // 执行测试方法
    service.applyDiscounts(items)
    
    // 验证函数调用(可选)
    expect(spy).toHaveBeenCalled()
  })
})

方案2:手动实现可迭代对象

如果需要自定义迭代逻辑,可手动实现带有[Symbol.iterator]方法的可迭代对象:

import * as DiscountUtil from '../discounts.ts'
describe('Process discount', () => {
  const service = new ProcessDiscountedItemsService()
  it('process item discounts verify', () =>{
    const items = /* 你的测试数据 */
    // 手动创建可迭代对象
    const mockIterable = {
      [Symbol.iterator]: function* () {
        yield [0, 0.1]
        yield [1, 0.2]
      }
    }
    // 监视并返回自定义可迭代对象
    const spy = jest.spyOn(DiscountUtil, 'createDiscounts') as jest.Mock
    spy.mockReturnValue(mockIterable)
    
    service.applyDiscounts(items)
    
    expect(spy).toHaveBeenCalled()
  })
})

业务代码修正

需将原业务代码中未定义的discounts变量修正为调用createDiscounts():

applyDiscounts = (items: OrderItem) => {
  const discounts = createDiscounts()
  for(let [number, discount] of discounts){
    // do logic
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 13:16:09