首页 > 解决方案 > 我如何使用 jest 来模拟一个 promisified 函数

问题描述

我有一个非常简单的小实用功能

xml2JSON如下

import { promisify } from 'util'
import { parseString } from 'xml2js'

const xml2js = promisify(parseString)

const xmlToJSON = async xml => xml2js(xml)

export default xmlToJSON

我试图开玩笑地测试它,嘲笑我不需要关心的东西

import * as util from 'util'
import * as xml2js from 'xml2js'

import xmlToJSON from './xmlToJSON'

jest.mock('util')
jest.mock('xml2js')

describe('xmlToJSON', () => {
  const promisifiedParseString = jest.fn()
  util.promisify = jest.fn(() => promisifiedParseString)
  const js = { some: 'result' }
  const xml = '<some>result</some>'
  let result

  beforeAll(async () => {
    promisifiedParseString.mockResolvedValue(js)
    result = await xmlToJSON(xml)
  })

  it('promisified the original parseString', () => {
    expect(util.promisify).toHaveBeenCalledWith(xml2js.parseString)
  })

  it('called the promisified parseString with the xml', () => {
    expect(promisifiedParseString).toHaveBeenCalledWith(xml)
  })

  it('returned the expected result', () => {
    expect(result).toEqual(js)
  })
})

但我得到了错误

TypeError: xml2js is not a function

  4 | const xml2js = promisify(parseString)
  5 | 
> 6 | const xmlToJSON = async xml => xml2js(xml)
    |                                ^
  7 | 
  8 | export default xmlToJSON
  9 | 

我究竟做错了什么?

更新

根据以下建议,我尝试更改导入顺序

import * as util from 'util'
import * as xml2js from 'xml2js'

jest.mock('util')
jest.mock('xml2js')
const promisifiedParseString = jest.fn()
util.promisify = jest.fn(() => promisifiedParseString)
import xmlToJSON from './xmlToJSON'

describe('xmlToJSON', () => {
  const js = { some: 'result' }
  const xml = '<some>result</some>'
  let result

  beforeAll(async () => {
    promisifiedParseString.mockResolvedValue(js)
    result = await xmlToJSON(xml)
  })

  it('promisified the original parseString', () => {
    expect(util.promisify).toHaveBeenCalledWith(xml2js.parseString)
  })

  it('called the promisified parseString with the xml', () => {
    expect(promisifiedParseString).toHaveBeenCalledWith(xml)
  })

  it('returned the expected result', () => {
    expect(result).toEqual(js)
  })
})

但这没什么区别

标签: node.jsmockingjestjs

解决方案


util.promisify在导入正在使用它的文件之前,您需要更改行为。

所以顺序应该是这样的:

util.promisify = jest.fn(() => promisifiedParseString)
import xmlToJSON from './xmlToJSON'

推荐阅读