首页 > 解决方案 > 在每次测试中重置 id 生成器的 Jest 模拟

问题描述

我正在尝试模拟 id 生成功能。我的generateIdsSet.js文件内容是:

import nanoid from 'nanoid/generate'

const generateId = (): string => {
  return nanoid('1234567890abcdefghijklmnopqrstuvwxyz', 5)
}

export const generateIdsSet = (setLength) => {
  const setIds = []

  for (let i = 0; i < setLength; i++) {
    setIds.push(generateId())
  }

  return setIds
}

在模拟文件generateIdsSet.spec.js中,generateIdsSet我需要创建可预测的 id 数组。我想出了那个实现:

import { generateIdsSet } from './generateIdsSet.js'

jest.mock('nanoid/generate', () => {
  let value = 0

  return () => String(++value)
})

describe('generateIdsSet', () => {
  it('One element', () => {
    expect(generateIdsSet(1)).toEqual(['1'])
  })

  it('Four elements', () => {
    expect(generateIdsSet(4)).toEqual(['1', '2', '3', '4'])
  })

  ....
})

一切都很好,除了每个测试计数器不会重置为 1 并且每次调用都保持递增。

也许这是我显然想念的东西,但我无法弄清楚。我将不胜感激。

标签: javascriptunit-testingtestingecmascript-6jestjs

解决方案


当您想模拟 ES 导入时,您还需要在测试文件中导入模块。有多种方法可以做到这一点,但最简单的两种方法是:

  • 使用autoMock并创建__mock__与测试相邻的目录(添加样板文件)
  • 在文件中导入要模拟的模块(更简单)
import nanoid from 'nanoid/generate'
import { generateIdsSet } from './generateIdsSet.js'

jest.mock('nanoid')

nanoid.mockImplementation(() => {
  let value = 0

  return () => String(++value)
});

afterAll(() => {
  // don't forget to restore when done!
  nanoid.mockRestore()
});

describe('generateIdsSet', () => {
  it('One element', () => {
    expect(generateIdsSet(1)).toEqual(['1'])
  })

  it('Four elements', () => {
    expect(generateIdsSet(4)).toEqual(['1', '2', '3', '4'])
  })

  ....
})

在这篇中等文章中可以找到更多嘲讽的好处(注意,我不是作者)。


推荐阅读