【问题标题】:Trouble mocking ES6 Module using jest.unstable_mockModule使用 jest.unstable_mockModule 模拟 ES6 模块时遇到问题
【发布时间】:2021-09-30 13:33:36
【问题描述】:

我正在尝试模拟对由被测代码导入的 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
  }
}

这是测试:

// 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()
  })
})

我正在尝试模拟对 Notify 的调用以期望它已被调用,虽然它会运行,但它会从应该被模拟的 Notifier.notify() 内部引发一个异常,所以看起来它不是根本不会被嘲笑。

我错过了什么?任何帮助深表感谢。 ????

【问题讨论】:

  • 您检查过main.fetch 返回的内容吗? respond 是否如你所愿抛出异常?
  • 是的,respond 确实引发了我所期望的异常,并且调用了通知程序,这反过来引发了一个异常,这是我不希望 notify() 被正确模拟的部分。

标签: javascript unit-testing jestjs


【解决方案1】:

我相信这是因为您在文件开头导入 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()
  })
})

【讨论】:

    【解决方案2】:

    我不完全理解最终的混乱。但是对于基础知识,要模拟导入类的特定属性/方法,您必须模拟类本身,然后模拟内部函数。

    因此,根据您的代码,您可以尝试以下操作:

    import { jest } from '@jest/globals'
    import main from '../src/Main.mjs'
    import Notifier from './Notifier.mjs'
    jest.mock('./Notifier.mjs', () => ({
        notify: jest.fn()
    }))
    
    describe('fetch', () => {
      test('Notifies on error', async () => {
        await main.fetch(null, null, null)
        expect(mockNotify).toHaveBeenCalled()
      })
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-10
      • 2012-08-07
      • 2012-01-07
      • 2013-06-14
      • 1970-01-01
      • 1970-01-01
      • 2018-02-18
      相关资源
      最近更新 更多