使用 spyOn 开玩笑模拟嵌套函数,但仍调用实际函数

时间:2021-02-21 04:35:48

标签: node.js unit-testing jestjs mocking spyon

getInfo 在同一个文件中调用 getColor。我的目的是模拟 getColor 函数,我将 func.js 作为模块导入并 spyOn getColor。模拟的 getColor 应该返回“Red”,但它仍然调用实际函数并返回“Black”。

函数文件

// func.js
function getColor() {
    return "black"
}

function getInfo(){
    const color = getColor()
    const size = "L"
    return `${color}-${size}`
}

module.exports = { getColor, getInfo }

测试文件

// func.test.js
const func = require("./func")

describe("Coverage Change Test", () => {
  beforeAll(() => {
    const colorMock = jest.spyOn(func, "getColor"); // spy on otherFn
    colorMock.mockImplementation(() => "Red");
  });

  afterAll(() => {
    colorMock.resetAllMocks();
  })

  test("return Large Red", async () => {
    const res = func.getInfo();
    expect(res).toEqual("Red-L");
  });
});

我也试过 requireActual,但它也调用了实际的。

const { getInfo, getColor } = require('./func');

jest.mock('./func', () => ({
  ...jest.requireActual('./func.'),
  getColor: jest.fn().mockImplementation(() => 'Red'),
}))

describe('test', () => {
  test('returns red', () => {
    const res = getInfo()
    expect(res).toEqual("Red-L")
  })
})

如何在 Jest 中正确模拟嵌套函数?提前致谢。

2 个答案:

答案 0 :(得分:0)

您正在监视 func.getColor 并模拟其实现,但 getInfo 正在调用本地范围的 getColor 函数。您必须更改调用 getColor 的方式才能模拟它。

exports.getColor = function() {
  return 'black'
}

exports.getInfo = function() {
  const color = exports.getColor()
  const size = 'L'
  return `${color}-${size}`
}

答案 1 :(得分:0)

使用 rewire 模块重写导出的属性。

您的测试文件将如下所示:

const rewire = require('rewire')

describe('test', () => {
  let func;
  let getColorSpy;
  beforeEach(() => {
    getColorSpy = jest.fn()
    func = rewire(__dirname + '/func.js') // import
    func.__set__('getColor', getColorSpy) // rewrite content of getColor
  })
  test('should return Red-L when getColor returns Red', () => {
    getColorSpy.mockReturnValue('Red')

    const res = func.getInfo()

    expect(res).toEqual("Red-L")
  })
})

尽量避免编写像模块一样的代码。

相关问题