19

I'm attempting to mock a call to a class instance function on an ES6 module being imported by the code under test. I've followed the progress of the ES6 support and eventually stumbled onto this PR https://github.com/facebook/jest/pull/10976 which mentioned that in 27.1.1 support for jest.unstable_mockModule was added. I upgraded my version of Jest to take advantage and while the test doesn't error, it also doesn't seem to actually mock the module either.

This is the module under test:

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

Here is the test:

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

I'm trying to mock the call to Notify to expect it to have been called and while this will run, it raises an exception from inside the Notifier.notify() that is supposed to be mocked, so it appears that it isn't being mocked at all.

What am I missing? Any help is much appreciated. 🙏

3
  • Have you checked to see what main.fetch is returning? Is respond throwing an exception as you expect? Commented Oct 3, 2021 at 21:25
  • 1
    Yes, respond does raise the exception as I expect and the call to notifier is made which in turn raises an exception which is the part I would not expect had notify() been mocked properly. Commented Oct 5, 2021 at 1:36
  • @rmontgomery429, did you get this work, or figure out a workable pattern? Commented Jul 23, 2022 at 17:53

1 Answer 1

17

I believe it's because you're importing main at the start of the file. You need to do a dynamic import the same way as 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()
  })
})
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.