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

使用Jest为导入的工具函数/自定义hook模拟多返回值的最佳方案

现有实现的问题

你当前代码里的useCount.jest.fn()写法是错误的,jest.fn()不是挂载在原hook函数上的方法,代码直接运行会抛出异常。

模拟方案选择

两种方式的适用场景和写法如下:

1. 全量模拟(不需要用到原hook实现时推荐)

如果你所有测试都不需要调用useCount的原始逻辑,直接用jest.mock做模块级模拟即可,写法最简单:

// 测试文件最顶部,所有import语句之前声明
jest.mock('../../hooks/useCount')

import { useCount } from '../../hooks/useCount'
import { ListItems } from '../ListItems'

const fruits = [
  'Apple', 'Banana', 'Cherry', 'Dragonfruit', 'Elderberry',
  'Fig', 'Grape', 'Huckleberry', 'Icaco', 'Jujube',
]

// 全局设置默认返回值,每次测试前重置避免用例之间互相影响
beforeEach(() => {
  useCount.mockReturnValue({ count: fruits.length + 1 })
})

describe(ListItems, () => {
  test('renders all items if count is greater than number of items', () => {
    const { getByText } = render(<ListItems items={fruits} />)
    // 断言逻辑和你原代码一致
  })

  test('renders the correct items if count is less than the number of items', () => {
    // 单测单独指定返回值,写法和你的预期一致
    useCount.mockReturnValueOnce({ count: 5 })
    const { getByText } = render(<ListItems items={fruits} />)
    // 断言逻辑和你原代码一致
  })
})

2. spyOn 模拟(需要保留原hook实现时推荐)

如果你有部分测试需要用到useCount的原始逻辑,用jest.spyOn更灵活,还可以随时恢复原实现:

import * as useCountModule from '../../hooks/useCount'
import { ListItems } from '../ListItems'

const fruits = [/* 水果数组同上 */]
const mockUseCount = jest.spyOn(useCountModule, 'useCount')

beforeEach(() => {
  // 重置mock状态,设置默认返回值
  mockUseCount.mockReset().mockReturnValue({ count: fruits.length + 1 })
})

// 如果你需要恢复原实现,调用 mockUseCount.mockRestore() 即可
Flow 类型冲突解决方案

冲突的原因是Flow无法识别普通函数被替换为Jest Mock函数的类型,三种解决方法:

  • 优先推荐用spyOn写法,jest.spyOn返回值本身就是Jest Mock类型,不需要额外处理就能兼容Flow类型校验
  • 手动做类型转换:
    const mockUseCount = (useCount: JestMockFn<[], {count: number}>)
    // 后续调用 mockUseCount.mockReturnValueOnce 不会报类型错误
    
  • 临时忽略类型校验,在对应行加Flow注释:
    // $FlowFixMe jest mock 类型特殊处理,忽略校验
    useCount.mockReturnValueOnce({ count: 5 })
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 16:24:03