如何使用 JEST 检查 Class 方法是否仅被调用一次

How to check if a Class method has been called only once with JEST

问题:

如何检查 Service.init() 方法是否只被调用过一次?

错误
expect(received).toHaveBeenCalledTimes(expected)

    Matcher error: received value must be a mock or spy function

    Received has type:  object
    Received has value: {"constructor": [Function Statistics], "init": [Function init]}

      13 |     const Module3 = Service
      14 |
    > 15 |     expect(Service).toHaveBeenCalledTimes(1)
         |                     ^
      16 |   })
      17 |

代码

index.spec.js:

  it('should initialized a class instance only once', async () => {
    const Service = require('./index')
    jest.mock('./index')

    const Module1 = Service
    const Module2 = Service
    const Module3 = Service

    expect(Service).toHaveBeenCalledTimes(1)
  })

基本上是一个 class 代码:

class Statistics {
  constructor () {
    console.log(' Constructor')
    this.init()
  }

  async init () {
    // Wait 500ms
    console.log(' Initializing')
    await new Promise(resolve => setTimeout(resolve('ok'), 500))
    console.log(' Initialization complete')
  }
}

module.exports = new Statistics()

您没有在检查之前调用该函数。文档中的示例 - 使用 .toHaveBeenCalledTimes 确保模拟函数被调用的确切次数。

例如,假设您有一个 drinkEach(drink, Array) 函数,它接受一个 drink 函数并将其应用于传递的饮料数组。您可能想要检查 drink 函数被调用的次数是否准确。您可以使用此测试套件做到这一点:

test('drinkEach drinks each drink', () => {
  const drink = jest.fn();
  drinkEach(drink, ['lemon', 'octopus']); // calling the function and checking it
  expect(drink).toHaveBeenCalledTimes(2);
});

在您的测试规范中,创建实例足以调用 init:

  it('should initialized a class instance only once', async () => {
    const Service = require('./index');
    jest.mock('./index')

    const Module1 = Service
    const Module2 = Service
    const Module3 = Service
    const mockServiceInstance = Service.init();
    expect(Service).toHaveBeenCalledTimes(1)
  })