kennethjiang/js-file-download

Can't mock the module in TypeScript

Closed this issue · 6 comments

Hey.

I'm having a very hard time mocking the fileDownload export. Not sure exactly how to do it correctly.

Error: Error: Uncaught [TypeError: js_file_download_1.default is not a function]

My attempt to mock.

// test.tsx

import fileDownload from 'js-file-download'

jest.mock('js-file-download', () => {
    return {
        _esModule: true,
        fileDownload: jest.fn(() => 'stuff'),
    }
})

window.URL.createObjectURL = jest.fn()
window.URL.revokeObjectURL = jest.fn()

test('returns the data when clicked', () => {
  
    // ... test implementation that renders a button and fires a click event.

    expect(fileDownload).toReturnWith('stuff')
})

I see now where I went wrong.

The default export is the fileDownload function. I guess I was attempting to mock a module.exports object.

@vilbergs I'm not using TypeScript, but how did you end up mocking it? I am also having trouble... I've tried:

jest.mock('js-file-download', () => jest.fn(console.trace))
// or
jest.mock('js-file-download', () => {
  return {
    __esModule: true,
    default: jest.fn(console.trace)
  }
})

which both print a trace that indicates it is being called in the correct place, but I cannot verify with expect. I even tried:

let mockFileDownloadCalled = false
jest.mock('js-file-download', () =>
  jest.fn(() => {
    console.trace()
    mockFileDownloadCalled = true
    console.log('fileDownload mockFileDownloadCalled', mockFileDownloadCalled)
  })
)

which logs that mockFileDownloadCalled is set to true, but is false back in the testcase when trying to verify with expect.

Hey!

Been a while since I worked on this and I don't have access to the source code any more.

You could try setting the second parameter directly as a jest.fn, but I'm just firing from the hip now.

jest.mock('js-file-download', jest.fn(() => {...}))

@jestrickler Could you show me how you're implementing this in your test? Is the mock in place before your test runs?

@vilbergs I've tried a couple ways. Please see https://stackoverflow.com/questions/64465087/how-to-mock-a-3rd-party-module-that-is-just-a-function-js-file-download. I think it's actually working, but maybe a timing issue where I need to waitFor the calls, but unfortunately I'm also using react-keyed-file-browser which has some issues with waitFor. I can print fileDownload.mock.calls at the point of call in my react component and see that it was called.

Thank you @vilbergs for being helpful. If at the end of this, you find that some documentation would be useful, please feel free to tag me or make a PR.