使用 jest.unstable_mockModule 模拟 ES6 模块时遇到问题

Rya*_*ery 17 javascript unit-testing jestjs

我正在尝试模拟对正在测试的代码导入的 ES6 模块上的类实例函数的调用。我一直在关注 ES6 支持的进展,最终偶然发现了这个 PR https://github.com/facebook/jest/pull/10976,其中提到在 27.1.1 中添加了对 jest.unstable_mockModule 的支持。我升级了 Jest 版本以利用这一优势,虽然测试没有错误,但它似乎也没有真正模拟该模块。

这是正在测试的模块:

// src/Main.mjs

import Responder from './Responder.mjs'
import Notifier from './Notifier.mjs'

export default {
  async fetch(request, environment, context) {
    let response

    try {
      response = new Responder(request, environment, context).respond()
    } catch (error) {
      return new Notifier().notify(error)
    }

    return response
  }
}
Run Code Online (Sandbox Code Playgroud)

这是测试:

// test/Main.test.mjs

import { jest } from '@jest/globals'
import main from '../src/Main.mjs'

describe('fetch', () => {
  test('Notifies on error', async () => {
    const mockNotify = jest.fn();
    
    jest.unstable_mockModule('../src/Notifier.mjs', () => ({
      notify: mockNotify
    }))

    const notifierMock = await import('../src/Notifier.mjs');
    
    await main.fetch(null, null, null)

    expect(mockNotify).toHaveBeenCalled()
  })
})
Run Code Online (Sandbox Code Playgroud)

我正在尝试模拟对 Notify 的调用,以期望它已被调用,并且当这将运行时,它会从Notifier.notify()应该被模拟的内部引发异常,因此看起来它根本没有被模拟。

我缺少什么?任何帮助深表感谢。

小智 14

我相信这是因为您在文件开头导入 main 。您需要以与 Notifier.mjs 相同的方式进行动态导入

// test/Main.test.mjs

import { jest } from '@jest/globals'


describe('fetch', () => {
  test('Notifies on error', async () => {
    const mockNotify = jest.fn();
    
    jest.unstable_mockModule('../src/Notifier.mjs', () => ({
      notify: mockNotify
    }))

    const notifierMock = await import('../src/Notifier.mjs');
    const main = await import('../src/Main.mjs');
    
    await main.fetch(null, null, null)

    expect(mockNotify).toHaveBeenCalled()
  })
})
Run Code Online (Sandbox Code Playgroud)